openapi: 3.1.0
info:
  title: Schulungstool API
  version: 1.0.0 (v1)
  description: REST API for users, groups, courses, participations, course ratings,
    and course categories.
paths:
  /v1/course-categories/:
    get:
      operationId: course_categories_list
      description: |-
        Required access: Course categories – Read (`course-categories:read`).

        This API endpoint returns a list of all course categories.
      parameters:
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a course category object.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order.
        schema:
          type: array
          items:
            type: string
            enum:
            - title
            - -title
            - created_at
            - -created_at
            - updated_at
            - -updated_at
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id` and `title` of
          a course category object.
        schema:
          type: string
      - in: query
        name: title
        schema:
          type: string
        description: A filter for the field `title` of a course category object.
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `updated_at` of a course category object:
          returns only course categories changed at the given time or later (ISO 8601;
          the given time itself is included). Together with `ordering=updated_at`,
          this allows delta queries instead of repeated full exports.'
      tags:
      - Course categories
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedCourseCategoryList'
              example:
                count: 3
                next: null
                previous: null
                results:
                - created_at: '2026-01-23T13:40:23'
                  id: 2d49d6d5-e286-4f06-9b83-b2fdc69475b1
                  title: General
                  updated_at: '2026-01-23T13:40:23'
                - created_at: '2026-01-23T13:42:21'
                  id: 071b2638-3ab5-409f-aa59-60c35c1158b0
                  title: Fire safety
                  updated_at: '2026-01-23T13:42:21'
                - created_at: '2026-01-23T13:41:51'
                  id: 7efd09ae-8a91-48c4-85bd-dd9bb604af9a
                  title: First aid
                  updated_at: '2026-01-23T13:41:51'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `course-categories:read` (Course categories
                    – Read). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: course-categories:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all course categories
      x-required-scope: course-categories:read
    post:
      operationId: course_categories_create
      description: |-
        Required access: Course categories – Read and write (`course-categories:write`).

        This API endpoint creates a course category.
      tags:
      - Course categories
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CourseCategoryRequest'
        required: true
      security:
      - ApiKey: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CourseCategory'
              example:
                created_at: '2026-01-23T13:40:23'
                id: 2d49d6d5-e286-4f06-9b83-b2fdc69475b1
                title: General
                updated_at: '2026-01-23T13:40:23'
          description: ''
          headers:
            Idempotent-Replayed:
              schema:
                type: boolean
              description: '`true` if this response is the stored response of an earlier
                request with the same `Idempotency-Key`; absent on first execution.'
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `course-categories:write` (Course categories
                    – Read and write). An administrator can grant it in the developer
                    options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: course-categories:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '422':
          description: The `Idempotency-Key` was already used for a different request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyReuseError
                  message: This Idempotency-Key was already used for a different request.
                    Use a new key for every new request.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '409':
          description: A request with the same `Idempotency-Key` is still in progress.
            Retry after the time given in `Retry-After`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyInUseError
                  message: A request with this Idempotency-Key is still in progress.
                    Wait for it to finish, then retry.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Makes the request safe to retry: resending it with the same
          key returns the stored response of the first successful execution instead
          of executing it again (for 24 hours). Failed attempts do not consume the
          key. Use a new key (for example a UUID) for every new operation, 1 to 200
          characters.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Create a course category
      x-required-scope: course-categories:write
  /v1/course-categories/{uuid}/:
    get:
      operationId: course_categories_retrieve
      description: |-
        Required access: Course categories – Read (`course-categories:read`).

        This API endpoint returns a course category.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the course category.
      tags:
      - Course categories
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CourseCategory'
              example:
                created_at: '2026-01-23T13:40:23'
                id: 2d49d6d5-e286-4f06-9b83-b2fdc69475b1
                title: General
                updated_at: '2026-01-23T13:40:23'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `course-categories:read` (Course categories
                    – Read). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: course-categories:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Retrieve a course category
      x-required-scope: course-categories:read
    patch:
      operationId: course_categories_partial_update
      description: |-
        Required access: Course categories – Read and write (`course-categories:write`).

        This API endpoint updates a course category.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the course category.
      tags:
      - Course categories
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedCourseCategoryRequest'
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CourseCategory'
              example:
                created_at: '2026-01-23T13:40:23'
                id: 2d49d6d5-e286-4f06-9b83-b2fdc69475b1
                title: General
                updated_at: '2026-02-01T12:30:10'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `course-categories:write` (Course categories
                    – Read and write). An administrator can grant it in the developer
                    options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: course-categories:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Update a course category
      x-required-scope: course-categories:write
    delete:
      operationId: course_categories_destroy
      description: |-
        Required access: Course categories – Read and write (`course-categories:write`).

        This API endpoint deletes a course category.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the course category.
      tags:
      - Course categories
      security:
      - ApiKey: []
      responses:
        '204':
          description: Success, no response data.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `course-categories:write` (Course categories
                    – Read and write). An administrator can grant it in the developer
                    options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: course-categories:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Delete a course category
      x-required-scope: course-categories:write
  /v1/course-ratings/:
    get:
      operationId: course_ratings_list
      parameters:
      - in: query
        name: course
        schema:
          type: string
          format: uuid
        description: A filter for the field `course` of a course rating object.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
        description: Fields to return as a full object instead of an ID.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a course rating object.
      - in: query
        name: language_code
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
        description: A filter for the field `language_code` of a course rating object.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order.
        schema:
          type: array
          items:
            type: string
            enum:
            - rating
            - -rating
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - in: query
        name: rating
        schema:
          type: integer
          title: Star rating
          enum:
          - 1
          - 2
          - 3
          - 4
          - 5
        description: A filter for the field `rating` of a course rating object.
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id`, `course` (`name`
          of the course object), and `comment` of a course rating object.
        schema:
          type: string
      tags:
      - Course ratings
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedCourseRatingList'
              example:
                count: 3
                next: null
                previous: null
                results:
                - comment: ''
                  course: 5716ad84-b7ba-4a7c-b2d2-7d9c46e04695
                  id: 9d4cf044-77fe-4aac-9dfa-2ee7e2a07f94
                  language_code: de
                  rating: 3
                - comment: I really liked the course.
                  course: ce9fb46d-0ade-4678-85f7-c6dbcdde3d86
                  id: 47244de2-3edd-448b-8ab7-6d4790046c79
                  language_code: de
                  rating: 5
                - comment: ''
                  course: 1e20e274-9ac1-45e8-9c2e-841e577ea292
                  id: 4c60786c-ca7e-4b3d-9932-24d8cb6702c9
                  language_code: de
                  rating: 1
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `course-ratings:read` (Course ratings
                    – Read). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: course-ratings:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all course ratings
      description: |-
        Required access: Course ratings – Read (`course-ratings:read`).

        This API endpoint returns a list of all course ratings. Ratings are anonymous: the ratings of a course are included only once at least five have been submitted for it.
      x-required-scope: course-ratings:read
  /v1/course-ratings/{uuid}/:
    get:
      operationId: course_ratings_retrieve
      parameters:
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
        description: Fields to return as a full object instead of an ID.
        explode: false
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the course rating.
      tags:
      - Course ratings
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CourseRating'
              example:
                comment: I really liked the course.
                course: ce9fb46d-0ade-4678-85f7-c6dbcdde3d86
                id: 47244de2-3edd-448b-8ab7-6d4790046c79
                language_code: de
                rating: 5
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `course-ratings:read` (Course ratings
                    – Read). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: course-ratings:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Retrieve a course rating
      description: |-
        Required access: Course ratings – Read (`course-ratings:read`).

        This API endpoint returns a course rating. Ratings are anonymous: a rating is available only once at least five have been submitted for its course.
      x-required-scope: course-ratings:read
  /v1/courses/:
    get:
      operationId: courses_list
      description: |-
        Required access: Courses – Read (`courses:read`).

        This API endpoint returns a list of all courses.
      parameters:
      - in: query
        name: category
        schema:
          type: string
          format: uuid
        description: A filter for the field `category` of a course object.
      - in: query
        name: description
        schema:
          type: string
        description: A filter for the field `description` of a course object.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - category
            - instructor
        description: Fields to return as a full object instead of an ID.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a course object.
      - in: query
        name: instructor
        schema:
          type: string
          format: uuid
        description: A filter for the field `instructor` of a course object.
      - in: query
        name: is_archived
        schema:
          type: boolean
        description: A filter for the field `is_archived` of a course object.
      - in: query
        name: lang
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
          default: de
        description: Language of the course content; if the course lacks it, the course's
          default language is used.
      - in: query
        name: name
        schema:
          type: string
        description: A filter for the field `name` of a course object.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order.
        schema:
          type: array
          items:
            type: string
            enum:
            - name
            - -name
            - created_at
            - -created_at
            - updated_at
            - -updated_at
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id`, `category` (`title`
          of the course category object), `name`, and `description` of a course object.
        schema:
          type: string
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `updated_at` of a course object: returns
          only courses changed at the given time or later (ISO 8601; the given time
          itself is included). Together with `ordering=updated_at`, this allows delta
          queries instead of repeated full exports. Changes to course contents also
          count as a change.'
      tags:
      - Courses
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedCourseList'
              example:
                count: 3
                next: null
                previous: null
                results:
                - category: 2d49d6d5-e286-4f06-9b83-b2fdc69475b1
                  created_at: '2026-01-11T08:25:16'
                  dashboard_url: https://demo.schulungstool.de/admin/courses/06285ae7-38a0-484a-b779-b11490c706c0/
                  default_language_code: de
                  description: This is the general course for 2026.
                  id: 06285ae7-38a0-484a-b779-b11490c706c0
                  instructor: af782ace-30a2-4628-837f-fcd807603631
                  is_archived: false
                  language_code: de
                  languages:
                    de: true
                    en: true
                    fr: false
                  name: General course 2026
                  thumbnail:
                    '1280':
                      height: 720
                      url: https://schulungscdn.de/schulungstool/cache/4c/18/4c185248455b1ff8d31626116a2e39e1.jpg
                      width: 1280
                    '160':
                      height: 90
                      url: https://schulungscdn.de/schulungstool/cache/5c/2f/5c2f699167cfaaed7f7bbdeb2094c62a.jpg
                      width: 160
                    '320':
                      height: 180
                      url: https://schulungscdn.de/schulungstool/cache/e6/f3/e6f31e65df15fe43d8a92663cccfeb3a.jpg
                      width: 320
                    '640':
                      height: 360
                      url: https://schulungscdn.de/schulungstool/cache/31/98/3198ec2a13fffa4abf3f6c48e2d0c606.jpg
                      width: 640
                  topics:
                  - Topic 1
                  - Topic 2
                  - Topic 3
                  updated_at: '2026-04-14T14:44:42'
                - category: 071b2638-3ab5-409f-aa59-60c35c1158b0
                  created_at: '2026-01-11T08:35:01'
                  dashboard_url: https://demo.schulungstool.de/admin/courses/fb86f4d4-bee3-4c70-9a25-8e9dd7fd9aab/
                  default_language_code: de
                  description: This is the course on fire safety.
                  id: fb86f4d4-bee3-4c70-9a25-8e9dd7fd9aab
                  instructor: 1e5d00d7-1f74-4531-9d9e-37ff9f95522b
                  is_archived: false
                  language_code: de
                  languages:
                    de: true
                  name: Fire safety course 2026
                  thumbnail:
                    '1280':
                      height: 720
                      url: https://schulungscdn.de/schulungstool/cache/4c/18/4c185248455b1ff8d31626116a2e39e1.jpg
                      width: 1280
                    '160':
                      height: 90
                      url: https://schulungscdn.de/schulungstool/cache/5c/2f/5c2f699167cfaaed7f7bbdeb2094c62a.jpg
                      width: 160
                    '320':
                      height: 180
                      url: https://schulungscdn.de/schulungstool/cache/e6/f3/e6f31e65df15fe43d8a92663cccfeb3a.jpg
                      width: 320
                    '640':
                      height: 360
                      url: https://schulungscdn.de/schulungstool/cache/31/98/3198ec2a13fffa4abf3f6c48e2d0c606.jpg
                      width: 640
                  topics: []
                  updated_at: '2026-03-21T08:18:58'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `courses:read` (Courses – Read). An
                    administrator can grant it in the developer options of the admin
                    area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: courses:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all courses
      x-required-scope: courses:read
    post:
      operationId: courses_create
      description: |-
        Required access: Courses – Read and write (`courses:write`).

        This API endpoint creates a course.
      tags:
      - Courses
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CourseRequest'
        required: true
      security:
      - ApiKey: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Course'
              example:
                category: 2d49d6d5-e286-4f06-9b83-b2fdc69475b1
                created_at: '2026-01-11T08:25:16'
                dashboard_url: https://demo.schulungstool.de/admin/courses/06285ae7-38a0-484a-b779-b11490c706c0/
                default_language_code: de
                description: This is the general course for 2026.
                id: 06285ae7-38a0-484a-b779-b11490c706c0
                instructor: af782ace-30a2-4628-837f-fcd807603631
                is_archived: false
                language_code: de
                languages:
                  de: true
                name: General course 2026
                thumbnail: null
                topics:
                - Topic 1
                - Topic 2
                - Topic 3
                updated_at: '2026-01-11T08:25:16'
          description: ''
          headers:
            Idempotent-Replayed:
              schema:
                type: boolean
              description: '`true` if this response is the stored response of an earlier
                request with the same `Idempotency-Key`; absent on first execution.'
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `courses:write` (Courses – Read and
                    write). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: courses:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '422':
          description: The `Idempotency-Key` was already used for a different request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyReuseError
                  message: This Idempotency-Key was already used for a different request.
                    Use a new key for every new request.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '409':
          description: A request with the same `Idempotency-Key` is still in progress.
            Retry after the time given in `Retry-After`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyInUseError
                  message: A request with this Idempotency-Key is still in progress.
                    Wait for it to finish, then retry.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Makes the request safe to retry: resending it with the same
          key returns the stored response of the first successful execution instead
          of executing it again (for 24 hours). Failed attempts do not consume the
          key. Use a new key (for example a UUID) for every new operation, 1 to 200
          characters.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Create a course
      x-required-scope: courses:write
  /v1/courses/{uuid}/:
    get:
      operationId: courses_retrieve
      description: |-
        Required access: Courses – Read (`courses:read`).

        This API endpoint returns a course.
      parameters:
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - category
            - instructor
        description: Fields to return as a full object instead of an ID.
        explode: false
      - in: query
        name: lang
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
          default: de
        description: Language of the course content; if the course lacks it, the course's
          default language is used.
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the course.
      tags:
      - Courses
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Course'
              example:
                category: 2d49d6d5-e286-4f06-9b83-b2fdc69475b1
                created_at: '2026-01-11T08:25:16'
                dashboard_url: https://demo.schulungstool.de/admin/courses/06285ae7-38a0-484a-b779-b11490c706c0/
                default_language_code: de
                description: This is the general course for 2026.
                id: 06285ae7-38a0-484a-b779-b11490c706c0
                instructor: af782ace-30a2-4628-837f-fcd807603631
                is_archived: false
                language_code: de
                languages:
                  de: true
                  en: true
                  fr: false
                name: General course 2026
                thumbnail:
                  '1280':
                    height: 720
                    url: https://schulungscdn.de/schulungstool/cache/4c/18/4c185248455b1ff8d31626116a2e39e1.jpg
                    width: 1280
                  '160':
                    height: 90
                    url: https://schulungscdn.de/schulungstool/cache/5c/2f/5c2f699167cfaaed7f7bbdeb2094c62a.jpg
                    width: 160
                  '320':
                    height: 180
                    url: https://schulungscdn.de/schulungstool/cache/e6/f3/e6f31e65df15fe43d8a92663cccfeb3a.jpg
                    width: 320
                  '640':
                    height: 360
                    url: https://schulungscdn.de/schulungstool/cache/31/98/3198ec2a13fffa4abf3f6c48e2d0c606.jpg
                    width: 640
                topics:
                - Topic 1
                - Topic 2
                - Topic 3
                updated_at: '2026-04-14T14:44:42'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `courses:read` (Courses – Read). An
                    administrator can grant it in the developer options of the admin
                    area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: courses:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Retrieve a course
      x-required-scope: courses:read
    patch:
      operationId: courses_partial_update
      description: |-
        Required access: Courses – Read and write (`courses:write`).

        This API endpoint updates a course.
      parameters:
      - in: query
        name: lang
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
          default: de
        description: The language whose course translation is edited (affects the
          fields `name`, `description`, and `topics`); if the course lacks it, the
          translation of the course's default language is edited.
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the course.
      tags:
      - Courses
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedCourseRequest'
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Course'
              example:
                category: 2d49d6d5-e286-4f06-9b83-b2fdc69475b1
                created_at: '2026-01-11T08:25:16'
                dashboard_url: https://demo.schulungstool.de/admin/courses/06285ae7-38a0-484a-b779-b11490c706c0/
                default_language_code: de
                description: This is the general course for 2026.
                id: 06285ae7-38a0-484a-b779-b11490c706c0
                instructor: af782ace-30a2-4628-837f-fcd807603631
                is_archived: false
                language_code: de
                languages:
                  de: true
                  en: true
                  fr: false
                name: General course 2026
                thumbnail:
                  '1280':
                    height: 720
                    url: https://schulungscdn.de/schulungstool/cache/4c/18/4c185248455b1ff8d31626116a2e39e1.jpg
                    width: 1280
                  '160':
                    height: 90
                    url: https://schulungscdn.de/schulungstool/cache/5c/2f/5c2f699167cfaaed7f7bbdeb2094c62a.jpg
                    width: 160
                  '320':
                    height: 180
                    url: https://schulungscdn.de/schulungstool/cache/e6/f3/e6f31e65df15fe43d8a92663cccfeb3a.jpg
                    width: 320
                  '640':
                    height: 360
                    url: https://schulungscdn.de/schulungstool/cache/31/98/3198ec2a13fffa4abf3f6c48e2d0c606.jpg
                    width: 640
                topics:
                - Topic 1
                - Topic 2
                - Topic 3
                updated_at: '2026-04-14T14:44:42'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `courses:write` (Courses – Read and
                    write). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: courses:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Update a course
      x-required-scope: courses:write
    delete:
      operationId: courses_destroy
      description: |-
        Required access: Courses – Read and write (`courses:write`).

        This API endpoint deletes a course.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the course.
      tags:
      - Courses
      security:
      - ApiKey: []
      responses:
        '204':
          description: Success, no response data.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `courses:write` (Courses – Read and
                    write). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: courses:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Delete a course
      x-required-scope: courses:write
  /v1/courses/{uuid}/participations/:
    get:
      operationId: courses_participations_retrieve
      description: |-
        Required access: Participations – Read (`participations:read`).

        This API endpoint returns a list of all participations of a course.
      parameters:
      - in: query
        name: lang
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
          default: de
        description: Language of the course content; if the course lacks it, the course's
          default language is used.
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the course.
      - in: query
        name: completed_at
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `completed_at` of a participation object;
          filters by the date (ISO 8601 date format: *YYYY-MM-DD*).'
      - in: query
        name: course
        schema:
          type: string
          format: uuid
        description: A filter for the field `course` of a participation object.
      - in: query
        name: due_date
        schema:
          type: string
          format: date
        description: A filter for the field `due_date` of a participation object.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
            - user
        description: Fields to return as a full object instead of an ID.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a participation object.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order. `user` sorts by the user's last name, `course`
          by the course name.
        schema:
          type: array
          items:
            type: string
            enum:
            - user
            - -user
            - course
            - -course
            - due_date
            - -due_date
            - completed_at
            - -completed_at
            - created_at
            - -created_at
            - updated_at
            - -updated_at
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id`, `user` (`username`,
          `first_name`, `last_name`, and `email` of the user object), and `course`
          (`name` of the course object) of a participation object.
        schema:
          type: string
      - in: query
        name: status
        schema:
          type: string
          enum:
          - done
          - pending
        description: A filter for the field `status` of a participation object.
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `updated_at` of a participation object:
          returns only participations changed at the given time or later (ISO 8601;
          the given time itself is included). Together with `ordering=updated_at`,
          this allows delta queries instead of repeated full exports.'
      - in: query
        name: user
        schema:
          type: string
          format: uuid
        description: A filter for the field `user` of a participation object.
      tags:
      - Courses
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedParticipationList'
              example:
                count: 3
                next: null
                previous: null
                results:
                - completed_at: null
                  course: ce9fb46d-0ade-4678-85f7-c6dbcdde3d86
                  created_at: '2026-01-11T09:17:45'
                  dashboard_url: https://demo.schulungstool.de/admin/participations/81b670f5-b160-4805-80fa-2cd1423bff9f/
                  due_date: '2025-06-30'
                  id: 81b670f5-b160-4805-80fa-2cd1423bff9f
                  learn_url: https://demo.schulungstool.de/learn/81b670f5-b160-4805-80fa-2cd1423bff9f/
                  status: pending
                  updated_at: '2026-01-11T09:17:45'
                  user: cd963a39-6070-4578-9d3b-23bb6a58432c
                - completed_at: '2025-03-15T13:37:25'
                  course: ce9fb46d-0ade-4678-85f7-c6dbcdde3d86
                  created_at: '2026-01-11T09:17:01'
                  dashboard_url: https://demo.schulungstool.de/admin/participations/d5d4665c-fe35-4e8a-98fc-73b7829b35a3/
                  due_date: '2025-06-30'
                  id: d5d4665c-fe35-4e8a-98fc-73b7829b35a3
                  learn_url: https://demo.schulungstool.de/learn/d5d4665c-fe35-4e8a-98fc-73b7829b35a3/
                  status: done
                  updated_at: '2025-03-15T13:37:26'
                  user: 1830fc24-b57a-41ba-93b1-9960f8edc927
                - completed_at: null
                  course: ce9fb46d-0ade-4678-85f7-c6dbcdde3d86
                  created_at: '2026-01-11T09:16:50'
                  dashboard_url: https://demo.schulungstool.de/admin/participations/f7c02638-199c-4e06-9b7c-89925e75b870/
                  due_date: '2025-06-30'
                  id: f7c02638-199c-4e06-9b7c-89925e75b870
                  learn_url: https://demo.schulungstool.de/learn/f7c02638-199c-4e06-9b7c-89925e75b870/
                  status: pending
                  updated_at: '2026-01-11T09:16:50'
                  user: dc8eee3e-cbbe-4f01-ab05-79d7cb882c2c
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `participations:read` (Participations
                    – Read). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: participations:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all participations of a course
      x-required-scope: participations:read
  /v1/courses/{uuid}/ratings/:
    get:
      operationId: courses_ratings_retrieve
      description: |-
        Required access: Course ratings – Read (`course-ratings:read`).

        This API endpoint returns a list of all ratings of a course. Ratings are anonymous: the list stays empty until at least five ratings have been submitted for the course.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the course.
      - in: query
        name: course
        schema:
          type: string
          format: uuid
        description: A filter for the field `course` of a course rating object.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
        description: Fields to return as a full object instead of an ID.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a course rating object.
      - in: query
        name: language_code
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
        description: A filter for the field `language_code` of a course rating object.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order.
        schema:
          type: array
          items:
            type: string
            enum:
            - rating
            - -rating
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - in: query
        name: rating
        schema:
          type: integer
          title: Star rating
          enum:
          - 1
          - 2
          - 3
          - 4
          - 5
        description: A filter for the field `rating` of a course rating object.
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id`, `course` (`name`
          of the course object), and `comment` of a course rating object.
        schema:
          type: string
      tags:
      - Courses
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedCourseRatingList'
              example:
                count: 3
                next: null
                previous: null
                results:
                - comment: ''
                  course: ce9fb46d-0ade-4678-85f7-c6dbcdde3d86
                  id: 20d3b11a-cb23-4986-bdfb-424c2ebdbdb4
                  language_code: de
                  rating: 3
                - comment: I really liked the course.
                  course: ce9fb46d-0ade-4678-85f7-c6dbcdde3d86
                  id: 47244de2-3edd-448b-8ab7-6d4790046c79
                  language_code: de
                  rating: 5
                - comment: top course
                  course: ce9fb46d-0ade-4678-85f7-c6dbcdde3d86
                  id: a75596f7-b044-4c42-9990-cdb43542adb1
                  language_code: en
                  rating: 5
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `course-ratings:read` (Course ratings
                    – Read). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: course-ratings:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all ratings of a course
      x-required-scope: course-ratings:read
  /v1/groups/:
    get:
      operationId: groups_list
      description: |-
        Required access: Groups – Read (`groups:read`).

        This API endpoint returns a list of all groups.
      parameters:
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a group object.
      - in: query
        name: name
        schema:
          type: string
        description: A filter for the field `name` of a group object.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order.
        schema:
          type: array
          items:
            type: string
            enum:
            - name
            - -name
            - created_at
            - -created_at
            - updated_at
            - -updated_at
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id`, `name`, and `description`
          of a group object.
        schema:
          type: string
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `updated_at` of a group object: returns
          only groups changed at the given time or later (ISO 8601; the given time
          itself is included). Together with `ordering=updated_at`, this allows delta
          queries instead of repeated full exports. Adding and removing members also
          counts as a change.'
      tags:
      - Groups
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedGroupList'
              example:
                count: 3
                next: null
                previous: null
                results:
                - created_at: '2024-12-06T11:55:22'
                  dashboard_url: https://demo.schulungstool.de/admin/groups/40c40d56-5e5e-438e-9642-184cc44e527a/
                  description: This group includes all employees.
                  id: 40c40d56-5e5e-438e-9642-184cc44e527a
                  name: All employees
                  updated_at: '2024-12-06T11:55:22'
                - created_at: '2024-12-06T12:17:29'
                  dashboard_url: https://demo.schulungstool.de/admin/groups/5679eb14-0268-40dc-890d-18ef5be6f835/
                  description: This group includes all employees in production.
                  id: 5679eb14-0268-40dc-890d-18ef5be6f835
                  name: Production
                  updated_at: '2026-04-17T08:07:52'
                - created_at: '2024-12-06T09:45:56'
                  dashboard_url: https://demo.schulungstool.de/admin/groups/b635a56e-25e1-4f68-995a-6aa07d8f7c19/
                  description: ''
                  id: b635a56e-25e1-4f68-995a-6aa07d8f7c19
                  name: Administration
                  updated_at: '2026-01-11T14:11:37'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `groups:read` (Groups – Read). An administrator
                    can grant it in the developer options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: groups:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all groups
      x-required-scope: groups:read
    post:
      operationId: groups_create
      description: |-
        Required access: Groups – Read and write (`groups:write`).

        This API endpoint creates a group.
      tags:
      - Groups
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupRequest'
        required: true
      security:
      - ApiKey: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
              example:
                created_at: '2024-12-06T11:55:22'
                dashboard_url: https://demo.schulungstool.de/admin/groups/40c40d56-5e5e-438e-9642-184cc44e527a/
                description: This group includes all employees.
                id: 40c40d56-5e5e-438e-9642-184cc44e527a
                name: All employees
                updated_at: '2024-12-06T11:55:22'
          description: ''
          headers:
            Idempotent-Replayed:
              schema:
                type: boolean
              description: '`true` if this response is the stored response of an earlier
                request with the same `Idempotency-Key`; absent on first execution.'
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `groups:write` (Groups – Read and write).
                    An administrator can grant it in the developer options of the
                    admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: groups:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '422':
          description: The `Idempotency-Key` was already used for a different request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyReuseError
                  message: This Idempotency-Key was already used for a different request.
                    Use a new key for every new request.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '409':
          description: A request with the same `Idempotency-Key` is still in progress.
            Retry after the time given in `Retry-After`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyInUseError
                  message: A request with this Idempotency-Key is still in progress.
                    Wait for it to finish, then retry.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Makes the request safe to retry: resending it with the same
          key returns the stored response of the first successful execution instead
          of executing it again (for 24 hours). Failed attempts do not consume the
          key. Use a new key (for example a UUID) for every new operation, 1 to 200
          characters.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Create a group
      x-required-scope: groups:write
  /v1/groups/{group_uuid}/members/{user_uuid}/:
    get:
      operationId: groups_members_check
      description: |-
        Required access: Groups – Read (`groups:read`).

        This API endpoint checks whether a user is a member of a group.
      parameters:
      - in: path
        name: group_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the group.
      - in: path
        name: user_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the user.
      tags:
      - Groups
      security:
      - ApiKey: []
      responses:
        '204':
          description: The user is a member of the group.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `groups:read` (Groups – Read). An administrator
                    can grant it in the developer options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: groups:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: The user is not a member of the group.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Check membership in a group
      x-required-scope: groups:read
    put:
      operationId: groups_members_update
      description: |-
        Required access: Groups – Read and write (`groups:write`).

        This API endpoint adds a member to a group.
      parameters:
      - in: path
        name: group_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the group.
      - in: path
        name: user_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the user.
      tags:
      - Groups
      security:
      - ApiKey: []
      responses:
        '204':
          description: Success, no response data.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `groups:write` (Groups – Read and write).
                    An administrator can grant it in the developer options of the
                    admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: groups:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Add a member to a group
      x-required-scope: groups:write
    delete:
      operationId: groups_members_destroy
      description: |-
        Required access: Groups – Read and write (`groups:write`).

        This API endpoint removes a member from a group.
      parameters:
      - in: path
        name: group_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the group.
      - in: path
        name: user_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the user.
      tags:
      - Groups
      security:
      - ApiKey: []
      responses:
        '204':
          description: Success, no response data.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `groups:write` (Groups – Read and write).
                    An administrator can grant it in the developer options of the
                    admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: groups:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Remove a member from a group
      x-required-scope: groups:write
  /v1/groups/{uuid}/:
    get:
      operationId: groups_retrieve
      description: |-
        Required access: Groups – Read (`groups:read`).

        This API endpoint returns a group.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the group.
      tags:
      - Groups
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
              example:
                created_at: '2024-12-06T11:55:22'
                dashboard_url: https://demo.schulungstool.de/admin/groups/40c40d56-5e5e-438e-9642-184cc44e527a/
                description: This group includes all employees.
                id: 40c40d56-5e5e-438e-9642-184cc44e527a
                name: All employees
                updated_at: '2024-12-06T11:55:22'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `groups:read` (Groups – Read). An administrator
                    can grant it in the developer options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: groups:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Retrieve a group
      x-required-scope: groups:read
    patch:
      operationId: groups_partial_update
      description: |-
        Required access: Groups – Read and write (`groups:write`).

        This API endpoint updates a group.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the group.
      tags:
      - Groups
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedGroupRequest'
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
              example:
                created_at: '2024-12-06T11:55:22'
                dashboard_url: https://demo.schulungstool.de/admin/groups/40c40d56-5e5e-438e-9642-184cc44e527a/
                description: This group includes all employees.
                id: 40c40d56-5e5e-438e-9642-184cc44e527a
                name: All employees
                updated_at: '2024-12-07T10:29:11'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `groups:write` (Groups – Read and write).
                    An administrator can grant it in the developer options of the
                    admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: groups:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Update a group
      x-required-scope: groups:write
    delete:
      operationId: groups_destroy
      description: |-
        Required access: Groups – Read and write (`groups:write`).

        This API endpoint deletes a group.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the group.
      tags:
      - Groups
      security:
      - ApiKey: []
      responses:
        '204':
          description: Success, no response data.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `groups:write` (Groups – Read and write).
                    An administrator can grant it in the developer options of the
                    admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: groups:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Delete a group
      x-required-scope: groups:write
  /v1/groups/{uuid}/members/:
    get:
      operationId: groups_members_retrieve
      description: |-
        Required access: Users – Read (`users:read`).

        This API endpoint returns a list of all members of a group.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the group.
      - in: query
        name: email
        schema:
          type: string
        description: A filter for the field `email` of a user object.
      - in: query
        name: first_name
        schema:
          type: string
        description: A filter for the field `first_name` of a user object.
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a user object.
      - in: query
        name: is_active
        schema:
          type: boolean
        description: A filter for the field `is_active` of a user object.
      - in: query
        name: language
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
        description: A filter for the field `language` of a user object.
      - in: query
        name: last_name
        schema:
          type: string
        description: A filter for the field `last_name` of a user object.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order.
        schema:
          type: array
          items:
            type: string
            enum:
            - username
            - -username
            - first_name
            - -first_name
            - last_name
            - -last_name
            - email
            - -email
            - last_active
            - -last_active
            - created_at
            - -created_at
            - updated_at
            - -updated_at
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - in: query
        name: requires_password_change
        schema:
          type: boolean
        description: A filter for the field `requires_password_change` of a user object.
      - in: query
        name: role
        schema:
          type: string
          enum:
          - admin
          - billing_manager
          - manager
          - user
        description: A filter for the field `role` of a user object.
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id`, `username`, `first_name`,
          `last_name`, `email`, and `description` of a user object.
        schema:
          type: string
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `updated_at` of a user object: returns
          only users changed at the given time or later (ISO 8601; the given time
          itself is included). Together with `ordering=updated_at`, this allows delta
          queries instead of repeated full exports. Adding and removing group memberships
          also counts as a change; mere activity (`last_active`) does not.'
      - in: query
        name: username
        schema:
          type: string
        description: A filter for the field `username` of a user object.
      tags:
      - Groups
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedUserList'
              example:
                count: 2
                next: null
                previous: null
                results:
                - birth_date: null
                  birth_place: ''
                  city: ''
                  country: ''
                  created_at: '2024-09-27T14:14:33'
                  dashboard_url: https://demo.schulungstool.de/admin/users/1f53398d-843f-4bc5-8e0f-9841ab294274/
                  deactivated_at: null
                  department: ''
                  description: ''
                  email: max.mustermann@example.com
                  first_name: Max
                  id: 1f53398d-843f-4bc5-8e0f-9841ab294274
                  is_active: true
                  job_title: ''
                  language: de
                  last_active: '2026-03-02T12:53:54'
                  last_name: Mustermann
                  notification_email: ''
                  organization: ''
                  phone: ''
                  postal_code: ''
                  requires_password_change: false
                  role: user
                  staff_number: '1'
                  street_address: ''
                  updated_at: '2026-04-17T08:05:47'
                  username: Max.Mustermann
                - birth_date: null
                  birth_place: ''
                  city: ''
                  country: ''
                  created_at: '2024-10-27T14:22:58'
                  dashboard_url: https://demo.schulungstool.de/admin/users/b23af455-a10b-4cf3-a981-ab592f45cffc/
                  deactivated_at: null
                  department: ''
                  description: User has been temporarily deactivated (parental leave).
                  email: erika.musterfrau@example.com
                  first_name: Erika
                  id: b23af455-a10b-4cf3-a981-ab592f45cffc
                  is_active: false
                  job_title: ''
                  language: de
                  last_active: '2024-11-28T11:18:06'
                  last_name: Musterfrau
                  notification_email: ''
                  organization: ''
                  phone: ''
                  postal_code: ''
                  requires_password_change: false
                  role: user
                  staff_number: '2'
                  street_address: ''
                  updated_at: '2026-04-13T10:04:28'
                  username: Erika.Musterfrau
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `users:read` (Users – Read). An administrator
                    can grant it in the developer options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: users:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all members of a group
      x-required-scope: users:read
  /v1/me/:
    get:
      operationId: me_retrieve
      description: 'Returns the API key used for the request: its name, ID, and access
        scopes, plus the account it belongs to. Works with any valid key regardless
        of its scopes – useful as a connection smoke test and to check which scopes
        a key carries.'
      tags:
      - API key
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                required:
                - key
                - organization
                properties:
                  key:
                    type: object
                    required:
                    - name
                    - uuid
                    - scopes
                    properties:
                      name:
                        type: string
                        description: Name of the API key, as assigned in the admin
                          area
                      uuid:
                        type: string
                        format: uuid
                        description: Stable ID of the API key
                      scopes:
                        type: array
                        items:
                          type: string
                          x-extensible-enum:
                          - users:read
                          - users:write
                          - groups:read
                          - groups:write
                          - courses:read
                          - courses:write
                          - course-categories:read
                          - course-categories:write
                          - course-ratings:read
                          - participations:read
                          - participations:write
                          - login-links:write
                        description: Access scopes of the key, sorted alphabetically
                  organization:
                    type: object
                    required:
                    - domain
                    properties:
                      domain:
                        type: string
                        description: Domain of the account the key belongs to
              example:
                key:
                  name: Reporting (read only)
                  scopes:
                  - course-ratings:read
                  - courses:read
                  - participations:read
                  uuid: 1e8f2d4c-9b7a-4f3e-8c21-5d6a7b8c9d0e
                organization:
                  domain: demo.schulungstool.de
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Get the current API key
  /v1/participations/:
    get:
      operationId: participations_list
      description: |-
        Required access: Participations – Read (`participations:read`).

        This API endpoint returns a list of all participations.
      parameters:
      - in: query
        name: completed_at
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `completed_at` of a participation object;
          filters by the date (ISO 8601 date format: *YYYY-MM-DD*).'
      - in: query
        name: course
        schema:
          type: string
          format: uuid
        description: A filter for the field `course` of a participation object.
      - in: query
        name: due_date
        schema:
          type: string
          format: date
        description: A filter for the field `due_date` of a participation object.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
            - user
        description: Fields to return as a full object instead of an ID.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a participation object.
      - in: query
        name: lang
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
          default: de
        description: Language of the course content; if the course lacks it, the course's
          default language is used.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order. `user` sorts by the user's last name, `course`
          by the course name.
        schema:
          type: array
          items:
            type: string
            enum:
            - user
            - -user
            - course
            - -course
            - due_date
            - -due_date
            - completed_at
            - -completed_at
            - created_at
            - -created_at
            - updated_at
            - -updated_at
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id`, `user` (`username`,
          `first_name`, `last_name`, and `email` of the user object), and `course`
          (`name` of the course object) of a participation object.
        schema:
          type: string
      - in: query
        name: status
        schema:
          type: string
          enum:
          - done
          - pending
        description: A filter for the field `status` of a participation object.
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `updated_at` of a participation object:
          returns only participations changed at the given time or later (ISO 8601;
          the given time itself is included). Together with `ordering=updated_at`,
          this allows delta queries instead of repeated full exports.'
      - in: query
        name: user
        schema:
          type: string
          format: uuid
        description: A filter for the field `user` of a participation object.
      tags:
      - Participations
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedParticipationList'
              example:
                count: 3
                next: null
                previous: null
                results:
                - completed_at: '2024-11-11T15:05:45'
                  course: 4aef42ee-f4b3-42e7-bf76-b321f105f64e
                  created_at: '2024-11-11T09:27:44'
                  dashboard_url: https://demo.schulungstool.de/admin/participations/2a84ea78-de46-433d-810a-f4d958d9d898/
                  due_date: '2026-02-12'
                  id: 2a84ea78-de46-433d-810a-f4d958d9d898
                  learn_url: https://demo.schulungstool.de/learn/2a84ea78-de46-433d-810a-f4d958d9d898/
                  status: done
                  updated_at: '2024-11-11T15:05:45'
                  user: 20d29b92-2757-454e-b373-c2fc0ab32cbf
                - completed_at: '2024-11-11T15:06:31'
                  course: 52065538-6f82-4cee-a3c1-3de904018aed
                  created_at: '2024-11-09T15:00:33'
                  dashboard_url: https://demo.schulungstool.de/admin/participations/8df2fa1e-5c5a-4d67-bcb1-39b1acf6b528/
                  due_date: '2024-12-11'
                  id: 8df2fa1e-5c5a-4d67-bcb1-39b1acf6b528
                  learn_url: https://demo.schulungstool.de/learn/8df2fa1e-5c5a-4d67-bcb1-39b1acf6b528/
                  status: done
                  updated_at: '2024-11-11T15:06:31'
                  user: 20d29b92-2757-454e-b373-c2fc0ab32cbf
                - completed_at: null
                  course: 6f061188-25a5-4899-a5df-bf975533149e
                  created_at: '2024-10-28T09:09:32'
                  dashboard_url: https://demo.schulungstool.de/admin/participations/0e7c942d-76b7-4bbf-a22e-3de5d872e1a6/
                  due_date: '2026-04-12'
                  id: 0e7c942d-76b7-4bbf-a22e-3de5d872e1a6
                  learn_url: https://demo.schulungstool.de/learn/0e7c942d-76b7-4bbf-a22e-3de5d872e1a6/
                  status: pending
                  updated_at: '2024-10-28T09:09:32'
                  user: be8b9e5e-c7eb-478b-8e8f-17d308e49a39
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `participations:read` (Participations
                    – Read). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: participations:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all participations
      x-required-scope: participations:read
    post:
      operationId: participations_create
      description: |-
        Required access: Participations – Read and write (`participations:write`).

        This API endpoint creates a participation.
        On request, the user is notified about the new participation by email, either immediately or at a time you choose. By default, no email is sent (see the body parameter `send_email_notification`).
      tags:
      - Participations
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ParticipationRequest'
        required: true
      security:
      - ApiKey: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Participation'
              example:
                completed_at: null
                course: 4aef42ee-f4b3-42e7-bf76-b321f105f64e
                created_at: '2026-10-05T09:27:44'
                dashboard_url: https://demo.schulungstool.de/admin/participations/2a84ea78-de46-433d-810a-f4d958d9d898/
                due_date: '2027-01-31'
                id: 2a84ea78-de46-433d-810a-f4d958d9d898
                learn_url: https://demo.schulungstool.de/learn/2a84ea78-de46-433d-810a-f4d958d9d898/
                status: pending
                updated_at: '2026-10-05T09:27:44'
                user: 20d29b92-2757-454e-b373-c2fc0ab32cbf
          description: ''
          headers:
            Idempotent-Replayed:
              schema:
                type: boolean
              description: '`true` if this response is the stored response of an earlier
                request with the same `Idempotency-Key`; absent on first execution.'
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `participations:write` (Participations
                    – Read and write). An administrator can grant it in the developer
                    options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: participations:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '422':
          description: The `Idempotency-Key` was already used for a different request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyReuseError
                  message: This Idempotency-Key was already used for a different request.
                    Use a new key for every new request.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '409':
          description: A request with the same `Idempotency-Key` is still in progress.
            Retry after the time given in `Retry-After`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyInUseError
                  message: A request with this Idempotency-Key is still in progress.
                    Wait for it to finish, then retry.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Makes the request safe to retry: resending it with the same
          key returns the stored response of the first successful execution instead
          of executing it again (for 24 hours). Failed attempts do not consume the
          key. Use a new key (for example a UUID) for every new operation, 1 to 200
          characters.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Create a participation
      x-required-scope: participations:write
  /v1/participations/{uuid}/:
    get:
      operationId: participations_retrieve
      description: |-
        Required access: Participations – Read (`participations:read`).

        This API endpoint returns a participation.
      parameters:
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
            - user
        description: Fields to return as a full object instead of an ID.
        explode: false
      - in: query
        name: lang
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
          default: de
        description: Language of the course content; if the course lacks it, the course's
          default language is used.
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the participation.
      tags:
      - Participations
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Participation'
              example:
                completed_at: '2024-11-11T15:05:45'
                course: 4aef42ee-f4b3-42e7-bf76-b321f105f64e
                created_at: '2024-11-11T09:27:44'
                dashboard_url: https://demo.schulungstool.de/admin/participations/2a84ea78-de46-433d-810a-f4d958d9d898/
                due_date: '2026-02-12'
                id: 2a84ea78-de46-433d-810a-f4d958d9d898
                learn_url: https://demo.schulungstool.de/learn/2a84ea78-de46-433d-810a-f4d958d9d898/
                status: done
                updated_at: '2024-11-11T15:05:45'
                user: 20d29b92-2757-454e-b373-c2fc0ab32cbf
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `participations:read` (Participations
                    – Read). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: participations:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Retrieve a participation
      x-required-scope: participations:read
    patch:
      operationId: participations_partial_update
      description: |-
        Required access: Participations – Read and write (`participations:write`).

        This API endpoint updates a participation.
        An email notification is only possible when creating a participation. The body parameters `send_email_notification`, `email_scheduled_at`, and `email_note` are ignored here.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the participation.
      tags:
      - Participations
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedParticipationRequest'
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Participation'
              example:
                completed_at: null
                course: 4aef42ee-f4b3-42e7-bf76-b321f105f64e
                created_at: '2026-01-11T09:27:44'
                dashboard_url: https://demo.schulungstool.de/admin/participations/96d5c8b6-5d16-48e4-9268-0383799eddee/
                due_date: '2026-12-31'
                id: 96d5c8b6-5d16-48e4-9268-0383799eddee
                learn_url: https://demo.schulungstool.de/learn/96d5c8b6-5d16-48e4-9268-0383799eddee/
                status: pending
                updated_at: '2026-02-01T15:05:45'
                user: 20d29b92-2757-454e-b373-c2fc0ab32cbf
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `participations:write` (Participations
                    – Read and write). An administrator can grant it in the developer
                    options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: participations:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Update a participation
      x-required-scope: participations:write
    delete:
      operationId: participations_destroy
      description: |-
        Required access: Participations – Read and write (`participations:write`).

        This API endpoint deletes a participation.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the participation.
      tags:
      - Participations
      security:
      - ApiKey: []
      responses:
        '204':
          description: Success, no response data.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `participations:write` (Participations
                    – Read and write). An administrator can grant it in the developer
                    options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: participations:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Delete a participation
      x-required-scope: participations:write
  /v1/participations/{uuid}/certificate/:
    get:
      operationId: participations_certificate_retrieve
      description: |-
        Required access: Participations – Read (`participations:read`).

        This API endpoint returns the certificate of a participation.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the participation.
      tags:
      - Participations
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/pdf:
              schema:
                type: string
                format: binary
          description: Certificate as a PDF.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `participations:read` (Participations
                    – Read). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: participations:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Retrieve the certificate of a participation
      x-required-scope: participations:read
  /v1/users/:
    get:
      operationId: users_list
      description: |-
        Required access: Users – Read (`users:read`).

        This API endpoint returns a list of all users.
      parameters:
      - in: query
        name: email
        schema:
          type: string
        description: A filter for the field `email` of a user object.
      - in: query
        name: first_name
        schema:
          type: string
        description: A filter for the field `first_name` of a user object.
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a user object.
      - in: query
        name: is_active
        schema:
          type: boolean
        description: A filter for the field `is_active` of a user object.
      - in: query
        name: language
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
        description: A filter for the field `language` of a user object.
      - in: query
        name: last_name
        schema:
          type: string
        description: A filter for the field `last_name` of a user object.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order.
        schema:
          type: array
          items:
            type: string
            enum:
            - username
            - -username
            - first_name
            - -first_name
            - last_name
            - -last_name
            - email
            - -email
            - last_active
            - -last_active
            - created_at
            - -created_at
            - updated_at
            - -updated_at
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - in: query
        name: requires_password_change
        schema:
          type: boolean
        description: A filter for the field `requires_password_change` of a user object.
      - in: query
        name: role
        schema:
          type: string
          enum:
          - admin
          - billing_manager
          - manager
          - user
        description: A filter for the field `role` of a user object.
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id`, `username`, `first_name`,
          `last_name`, `email`, and `description` of a user object.
        schema:
          type: string
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `updated_at` of a user object: returns
          only users changed at the given time or later (ISO 8601; the given time
          itself is included). Together with `ordering=updated_at`, this allows delta
          queries instead of repeated full exports. Adding and removing group memberships
          also counts as a change; mere activity (`last_active`) does not.'
      - in: query
        name: username
        schema:
          type: string
        description: A filter for the field `username` of a user object.
      tags:
      - Users
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedUserList'
              example:
                count: 2
                next: null
                previous: null
                results:
                - birth_date: '1990-02-04'
                  birth_place: Berlin
                  city: Berlin
                  country: DE
                  created_at: '2025-09-27T14:14:33'
                  dashboard_url: https://demo.schulungstool.de/admin/users/1f53398d-843f-4bc5-8e0f-9841ab294274/
                  deactivated_at: null
                  department: Logistics
                  description: Description of the user
                  email: max.mustermann@example.com
                  first_name: Max
                  id: 1f53398d-843f-4bc5-8e0f-9841ab294274
                  is_active: true
                  job_title: ''
                  language: de
                  last_active: '2026-03-02T12:53:54'
                  last_name: Mustermann
                  notification_email: ''
                  organization: Musterfirma GmbH
                  phone: ''
                  postal_code: ''
                  requires_password_change: false
                  role: user
                  staff_number: '1'
                  street_address: ''
                  updated_at: '2026-04-17T08:05:47'
                  username: Max.Mustermann
                - birth_date: '1984-12-12'
                  birth_place: ''
                  city: ''
                  country: ''
                  created_at: '2024-10-27T14:22:58'
                  dashboard_url: https://demo.schulungstool.de/admin/users/b23af455-a10b-4cf3-a981-ab592f45cffc/
                  deactivated_at: null
                  department: ''
                  description: User has been temporarily deactivated (parental leave).
                  email: erika.musterfrau@example.com
                  first_name: Erika
                  id: b23af455-a10b-4cf3-a981-ab592f45cffc
                  is_active: false
                  job_title: ''
                  language: de
                  last_active: '2025-11-28T11:18:06'
                  last_name: Musterfrau
                  notification_email: ''
                  organization: Musterfirma GmbH
                  phone: ''
                  postal_code: ''
                  requires_password_change: false
                  role: user
                  staff_number: '2'
                  street_address: ''
                  updated_at: '2026-04-13T10:04:28'
                  username: Erika.Musterfrau
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `users:read` (Users – Read). An administrator
                    can grant it in the developer options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: users:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all users
      x-required-scope: users:read
    post:
      operationId: users_create
      description: |-
        Required access: Users – Read and write (`users:write`).

        This API endpoint creates a user. If you create the user with an initial password, set `requires_password_change` to `true`: the user must then replace the password with one of their own at their first login.
      tags:
      - Users
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserRequest'
        required: true
      security:
      - ApiKey: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
              example:
                birth_date: '1990-02-04'
                birth_place: Berlin
                city: Berlin
                country: DE
                created_at: '2024-09-27T14:14:33'
                dashboard_url: https://demo.schulungstool.de/admin/users/1f53398d-843f-4bc5-8e0f-9841ab294274/
                deactivated_at: null
                department: Logistics
                description: Description of the user
                email: max.mustermann@example.com
                first_name: Max
                id: 1f53398d-843f-4bc5-8e0f-9841ab294274
                is_active: true
                job_title: ''
                language: de
                last_active: null
                last_name: Mustermann
                notification_email: ''
                organization: Musterfirma GmbH
                phone: ''
                postal_code: ''
                requires_password_change: false
                role: user
                staff_number: '1'
                street_address: ''
                updated_at: '2024-09-27T14:14:33'
                username: Max.Mustermann
          description: ''
          headers:
            Idempotent-Replayed:
              schema:
                type: boolean
              description: '`true` if this response is the stored response of an earlier
                request with the same `Idempotency-Key`; absent on first execution.'
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `users:write` (Users – Read and write).
                    An administrator can grant it in the developer options of the
                    admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: users:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '422':
          description: The `Idempotency-Key` was already used for a different request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyReuseError
                  message: This Idempotency-Key was already used for a different request.
                    Use a new key for every new request.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '409':
          description: A request with the same `Idempotency-Key` is still in progress.
            Retry after the time given in `Retry-After`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyInUseError
                  message: A request with this Idempotency-Key is still in progress.
                    Wait for it to finish, then retry.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Makes the request safe to retry: resending it with the same
          key returns the stored response of the first successful execution instead
          of executing it again (for 24 hours). Failed attempts do not consume the
          key. Use a new key (for example a UUID) for every new operation, 1 to 200
          characters.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Create a user
      x-required-scope: users:write
  /v1/users/{uuid}/:
    get:
      operationId: users_retrieve
      description: |-
        Required access: Users – Read (`users:read`).

        This API endpoint returns a user.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the user.
      tags:
      - Users
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
              example:
                birth_date: '1990-02-04'
                birth_place: Berlin
                city: Berlin
                country: DE
                created_at: '2024-09-27T14:14:33'
                dashboard_url: https://demo.schulungstool.de/admin/users/1f53398d-843f-4bc5-8e0f-9841ab294274/
                deactivated_at: null
                department: Logistics
                description: Description of the user
                email: max.mustermann@example.com
                first_name: Max
                id: 1f53398d-843f-4bc5-8e0f-9841ab294274
                is_active: true
                job_title: ''
                language: de
                last_active: null
                last_name: Mustermann
                notification_email: ''
                organization: Musterfirma GmbH
                phone: ''
                postal_code: ''
                requires_password_change: false
                role: user
                staff_number: '1'
                street_address: ''
                updated_at: '2024-09-27T14:14:33'
                username: Max.Mustermann
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `users:read` (Users – Read). An administrator
                    can grant it in the developer options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: users:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Retrieve a user
      x-required-scope: users:read
    patch:
      operationId: users_partial_update
      description: |-
        Required access: Users – Read and write (`users:write`).

        This API endpoint updates a user. Only the fields you send are changed. A new `password` on its own leaves `requires_password_change` unchanged; send both fields together to assign an initial password and require a change at the next login.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the user.
      tags:
      - Users
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedUserRequest'
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
              example:
                birth_date: '1990-02-04'
                birth_place: Berlin
                city: Berlin
                country: DE
                created_at: '2024-09-27T14:14:33'
                dashboard_url: https://demo.schulungstool.de/admin/users/1f53398d-843f-4bc5-8e0f-9841ab294274/
                deactivated_at: null
                department: Logistics
                description: Description of the user
                email: max.mustermann@example.com
                first_name: Max
                id: 1f53398d-843f-4bc5-8e0f-9841ab294274
                is_active: true
                job_title: Warehouse logistics specialist
                language: de
                last_active: null
                last_name: Mustermann
                notification_email: mmustermann.privat@gmail.com
                organization: Musterfirma GmbH
                phone: ''
                postal_code: ''
                requires_password_change: false
                role: user
                staff_number: '1'
                street_address: ''
                updated_at: '2024-09-27T14:14:33'
                username: Max.Mustermann
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `users:write` (Users – Read and write).
                    An administrator can grant it in the developer options of the
                    admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: users:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Update a user
      x-required-scope: users:write
    delete:
      operationId: users_destroy
      description: |-
        Required access: Users – Read and write (`users:write`).

        This API endpoint deletes a user.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the user.
      tags:
      - Users
      security:
      - ApiKey: []
      responses:
        '204':
          description: Success, no response data.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `users:write` (Users – Read and write).
                    An administrator can grant it in the developer options of the
                    admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: users:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Delete a user
      x-required-scope: users:write
  /v1/users/{uuid}/groups/:
    get:
      operationId: users_groups_retrieve
      description: |-
        Required access: Groups – Read (`groups:read`).

        This API endpoint returns a list of all groups of a user.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the user.
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a group object.
      - in: query
        name: name
        schema:
          type: string
        description: A filter for the field `name` of a group object.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order.
        schema:
          type: array
          items:
            type: string
            enum:
            - name
            - -name
            - created_at
            - -created_at
            - updated_at
            - -updated_at
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id`, `name`, and `description`
          of a group object.
        schema:
          type: string
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `updated_at` of a group object: returns
          only groups changed at the given time or later (ISO 8601; the given time
          itself is included). Together with `ordering=updated_at`, this allows delta
          queries instead of repeated full exports. Adding and removing members also
          counts as a change.'
      tags:
      - Users
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedGroupList'
              example:
                count: 2
                next: null
                previous: null
                results:
                - created_at: '2024-12-06T11:55:22'
                  dashboard_url: https://demo.schulungstool.de/admin/groups/40c40d56-5e5e-438e-9642-184cc44e527a/
                  description: This group includes all employees.
                  id: 40c40d56-5e5e-438e-9642-184cc44e527a
                  name: All employees
                  updated_at: '2024-12-06T11:55:22'
                - created_at: '2024-12-06T12:17:29'
                  dashboard_url: https://demo.schulungstool.de/admin/groups/5679eb14-0268-40dc-890d-18ef5be6f835/
                  description: This group includes all employees in production.
                  id: 5679eb14-0268-40dc-890d-18ef5be6f835
                  name: Production
                  updated_at: '2026-04-17T08:07:52'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `groups:read` (Groups – Read). An administrator
                    can grant it in the developer options of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: groups:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all groups of a user
      x-required-scope: groups:read
  /v1/users/{uuid}/login-link/:
    post:
      operationId: users_login_link_create
      description: "Required access: Login links – Allow (`login-links:write`).\n\nThis
        API endpoint creates a login link for a user. Login links are also known as
        <q>magic links</q>.\nWith login links, users can be signed in to Schulungstool
        without a password.\nWhen a user is redirected to the login link, they are
        signed in automatically.\nYou can append the parameter `?next=<redirect-url>`
        to the login link. After the login, the user is automatically redirected to
        the `<redirect-url>` (for example, the `learn_url` of a participation). If
        the user has `requires_password_change: true`, they first set a new password
        after the login; the redirect to the `<redirect-url>` follows afterwards.\nLimitations:\n-
        Login links can only be created for users with the role `user`. \n- Login
        links are only valid for 30 seconds. It is best to create a login link immediately
        before using it."
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the user.
      - name: Idempotency-Key
        in: header
        required: false
        description: Accepted and validated, but responses of this endpoint are never
          stored or replayed, because the generated link expires after a short time.
          Every request creates a fresh link.
        schema:
          type: string
          minLength: 1
          maxLength: 200
      tags:
      - Users
      security:
      - ApiKey: []
      responses:
        '201':
          content:
            application/json:
              schema:
                type: object
                properties:
                  url:
                    type: string
                    format: uri
                    description: The generated login link.
              example:
                url: https://demo.schulungstool.de/accounts/login/3c1dd117-0d56-4e88-adc0-cd22977a3fb0:1rVd0d:ZOJ9Wc49-CaJdehS-t9ZswFGqh696QDEbDtAn-oEDd8/
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `login-links:write` (Login links – Allow).
                    An administrator can grant it in the developer options of the
                    admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: login-links:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '422':
          description: The `Idempotency-Key` was already used for a different request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyReuseError
                  message: This Idempotency-Key was already used for a different request.
                    Use a new key for every new request.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Invalid `Idempotency-Key` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyInvalidError
                  message: The Idempotency-Key header must be between 1 and 200 characters
                    long.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: Create a login link
      x-required-scope: login-links:write
  /v1/users/{uuid}/participations/:
    get:
      operationId: users_participations_retrieve
      description: |-
        Required access: Participations – Read (`participations:read`).

        This API endpoint returns a list of all participations of a user.
      parameters:
      - in: query
        name: lang
        schema:
          type: string
          enum:
          - ar
          - bg
          - bs
          - cs
          - de
          - el
          - en
          - es
          - fa
          - fr
          - hi
          - hr
          - hu
          - it
          - ja
          - mk
          - nl
          - pl
          - pt
          - ro
          - ru
          - sk
          - sl
          - sq
          - sr
          - ta
          - tl
          - tr
          - uk
          - ur
          - vi
          - zh-hans
          default: de
        description: Language of the course content; if the course lacks it, the course's
          default language is used.
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: The ID of the user.
      - in: query
        name: completed_at
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `completed_at` of a participation object;
          filters by the date (ISO 8601 date format: *YYYY-MM-DD*).'
      - in: query
        name: course
        schema:
          type: string
          format: uuid
        description: A filter for the field `course` of a participation object.
      - in: query
        name: due_date
        schema:
          type: string
          format: date
        description: A filter for the field `due_date` of a participation object.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
            - user
        description: Fields to return as a full object instead of an ID.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: A filter for the field `id` of a participation object.
      - name: ordering
        in: query
        required: false
        description: Sort order; several fields separated by commas; a leading `-`
          sorts in descending order. `user` sorts by the user's last name, `course`
          by the course name.
        schema:
          type: array
          items:
            type: string
            enum:
            - user
            - -user
            - course
            - -course
            - due_date
            - -due_date
            - completed_at
            - -completed_at
            - created_at
            - -created_at
            - updated_at
            - -updated_at
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Number of results per page, between 1 and 100 (default: 25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: A search term, matched against the fields `id`, `user` (`username`,
          `first_name`, `last_name`, and `email` of the user object), and `course`
          (`name` of the course object) of a participation object.
        schema:
          type: string
      - in: query
        name: status
        schema:
          type: string
          enum:
          - done
          - pending
        description: A filter for the field `status` of a participation object.
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'A filter for the field `updated_at` of a participation object:
          returns only participations changed at the given time or later (ISO 8601;
          the given time itself is included). Together with `ordering=updated_at`,
          this allows delta queries instead of repeated full exports.'
      - in: query
        name: user
        schema:
          type: string
          format: uuid
        description: A filter for the field `user` of a participation object.
      tags:
      - Users
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaginatedParticipationList'
              example:
                count: 2
                next: null
                previous: null
                results:
                - completed_at: null
                  course: ce9fb46d-0ade-4678-85f7-c6dbcdde3d86
                  created_at: '2026-04-04T14:21:14'
                  dashboard_url: https://demo.schulungstool.de/admin/participations/a3afcc8e-9c3d-43c2-80e2-70912ef9c05e/
                  due_date: '2026-06-30'
                  id: a3afcc8e-9c3d-43c2-80e2-70912ef9c05e
                  learn_url: https://demo.schulungstool.de/learn/a3afcc8e-9c3d-43c2-80e2-70912ef9c05e/
                  status: pending
                  updated_at: '2026-04-04T14:21:14'
                  user: 1f53398d-843f-4bc5-8e0f-9841ab294274
                - completed_at: '2024-10-27T14:27:17'
                  course: 6f061188-25a5-4899-a5df-bf975533149e
                  created_at: '2025-09-01T14:15:58'
                  dashboard_url: https://demo.schulungstool.de/admin/participations/65ef95d4-5352-496a-88b1-e1d194b8dc0a/
                  due_date: '2025-10-30'
                  id: 65ef95d4-5352-496a-88b1-e1d194b8dc0a
                  learn_url: https://demo.schulungstool.de/learn/65ef95d4-5352-496a-88b1-e1d194b8dc0a/
                  status: done
                  updated_at: '2025-10-27T14:27:17'
                  user: 1f53398d-843f-4bc5-8e0f-9841ab294274
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `participations:read` (Participations
                    – Read). An administrator can grant it in the developer options
                    of the admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: participations:read
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: NotFound
                  message: Resource not found.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    page_size:
                    - Must be an integer between 1 and 100.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      summary: List all participations of a user
      x-required-scope: participations:read
  /v1/users/invite/:
    post:
      operationId: users_invite_create
      description: |-
        Required access: Users – Read and write (`users:write`).

        This API endpoint invites a user by email.
      tags:
      - Users
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserInviteRequest'
        required: true
      security:
      - ApiKey: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
              example:
                birth_date: null
                birth_place: ''
                city: ''
                country: ''
                created_at: '2024-09-27T14:14:33'
                dashboard_url: https://demo.schulungstool.de/admin/users/1f53398d-843f-4bc5-8e0f-9841ab294274/
                deactivated_at: null
                department: ''
                description: ''
                email: max.mustermann@example.com
                first_name: Max
                id: 1f53398d-843f-4bc5-8e0f-9841ab294274
                is_active: true
                job_title: ''
                language: de
                last_active: null
                last_name: Mustermann
                notification_email: ''
                organization: ''
                phone: ''
                postal_code: ''
                requires_password_change: false
                role: user
                staff_number: ''
                street_address: ''
                updated_at: '2024-09-27T14:14:33'
                username: max.mustermann
          description: ''
          headers:
            Idempotent-Replayed:
              schema:
                type: boolean
              description: '`true` if this response is the stored response of an earlier
                request with the same `Idempotency-Key`; absent on first execution.'
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '401':
          description: API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: AuthenticationFailed
                  message: Invalid token.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '403':
          description: API key lacks the access scope this endpoint requires; `error.required_scope`
            names it. An administrator can grant it in the developer options of the
            admin area.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: MissingScope
                  message: 'This API key does not have the required access for this
                    endpoint. Required scope: `users:write` (Users – Read and write).
                    An administrator can grant it in the developer options of the
                    admin area.'
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  required_scope: users:write
                  doc_url: https://docs.api.schulungstool.de/guides/authentication/#access-scopes
          headers:
            X-Required-Scope:
              schema:
                type: string
              description: The missing access scope (same value as `error.required_scope`
                in the body).
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
        '429':
          description: Rate limit reached (1000 requests per minute per account).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: Throttled
                  message: Request was throttled. Expected available in 7 seconds.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '400':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: ValidationError
                  message: One or more fields are missing or have invalid values.
                    See `field_errors` and `non_field_errors` for details.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
                  field_errors:
                    due_date:
                    - This field is required.
                  non_field_errors: []
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '422':
          description: The `Idempotency-Key` was already used for a different request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyReuseError
                  message: This Idempotency-Key was already used for a different request.
                    Use a new key for every new request.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
        '409':
          description: A request with the same `Idempotency-Key` is still in progress.
            Retry after the time given in `Retry-After`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  type: IdempotencyKeyInUseError
                  message: A request with this Idempotency-Key is still in progress.
                    Wait for it to finish, then retry.
                  request_id: req_6b1c9d2e4f3a5078b6c4d2e0
          headers:
            Retry-After:
              schema:
                type: integer
              description: Wait time in seconds.
            X-Request-ID:
              schema:
                type: string
              description: Unique ID of this request; errors repeat it in the body.
                Include it in support inquiries.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximum number of requests allowed in the current rate
                limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Requests still available in the current rate limit window,
                after this request.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Time at which at least one request becomes available again,
                as a Unix timestamp in seconds.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Makes the request safe to retry: resending it with the same
          key returns the stored response of the first successful execution instead
          of executing it again (for 24 hours). Failed attempts do not consume the
          key. Use a new key (for example a UUID) for every new operation, 1 to 200
          characters.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Invite a user
      x-required-scope: users:write
components:
  schemas:
    BlankEnum:
      enum:
      - ''
    CountryEnum:
      enum:
      - DE
      - AT
      - CH
      - BE
      - BG
      - HR
      - CY
      - CZ
      - DK
      - EE
      - FI
      - FR
      - GR
      - HU
      - IE
      - IT
      - LV
      - LT
      - LU
      - MT
      - NL
      - PL
      - PT
      - RO
      - SK
      - SI
      - ES
      - SE
      type: string
    Course:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: ID of the course
        category:
          type:
          - string
          - 'null'
          format: uuid
          description: ID of the course category. This field is expandable.
        name:
          type: string
          readOnly: true
          description: Name of the course (translated into the `language_code` of
            the course object)
        description:
          type: string
          readOnly: true
          description: Description of the course (translated into the `language_code`
            of the course object)
        topics:
          type: array
          items:
            type: string
          readOnly: true
          description: Topics of the course (translated into the `language_code` of
            the course object)
        thumbnail:
          type:
          - object
          - 'null'
          additionalProperties:
            type: object
            properties:
              url:
                type: string
                format: uri
              width:
                type: integer
              height:
                type: integer
          readOnly: true
          description: |-
            Thumbnail of the course in several resolutions

            *Key*: width of the thumbnail

            *Value*: `Object` with the *keys* `url` (URL of the thumbnail), `width` (width of the thumbnail in pixels), and `height` (height of the thumbnail in pixels).
        instructor:
          type:
          - string
          - 'null'
          format: uuid
          description: ID of the instructor. This field is expandable.
        languages:
          type: object
          readOnly: true
          additionalProperties:
            type: boolean
          description: |-
            Translations of the course

            *Key*: ISO 639-1 language code, e.g. `"de"`

            *Value*: `true` (translation is enabled) or `false` (translation is disabled)
        language_code:
          type: string
          readOnly: true
          description: Current translation of the course object (ISO 639-1 language
            code, e.g. `"de"`)
        default_language_code:
          $ref: '#/components/schemas/LanguageEnum'
          description: Default language of the course (ISO 639-1 language code, e.g.
            `"de"`)
        is_archived:
          type: boolean
          description: |-
            `true`: course is archived

            `false`: course is not archived
        created_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time the course was created
        updated_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time the course was last updated
        dashboard_url:
          type: string
          format: uri
          readOnly: true
          description: URL of the course's detail view in the admin area of your Schulungstool
            account
      required:
      - created_at
      - dashboard_url
      - default_language_code
      - description
      - id
      - instructor
      - language_code
      - languages
      - name
      - thumbnail
      - topics
      - updated_at
    CourseCategory:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: ID of the course category
        title:
          type: string
          maxLength: 50
          description: Title of the course category
        created_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time the course category was created
        updated_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time the course category was last updated
      required:
      - created_at
      - id
      - title
      - updated_at
    CourseCategoryRequest:
      type: object
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 50
          description: Title of the course category
      required:
      - title
    CourseRating:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: ID of the course rating
        course:
          type: string
          format: uuid
          readOnly: true
          description: ID of the rated course. This field is expandable.
        language_code:
          allOf:
          - $ref: '#/components/schemas/LanguageEnum'
          readOnly: true
          description: Rated translation of the course (ISO 639-1 language code, e.g.
            `"de"`)
        rating:
          allOf:
          - $ref: '#/components/schemas/RatingEnum'
          readOnly: true
          description: Rating of the course, from 1 to 5 stars
        comment:
          type: string
          readOnly: true
          description: Comment on the course rating
      required:
      - comment
      - course
      - id
      - language_code
      - rating
    CourseRequest:
      type: object
      properties:
        category:
          type:
          - string
          - 'null'
          format: uuid
          description: ID of the course category. This field is expandable.
          default: null
        name:
          type: string
          minLength: 1
          maxLength: 250
          description: Name of the course (translated into the `language_code` of
            the course object)
        description:
          type: string
          description: Description of the course (translated into the `language_code`
            of the course object)
          default: ''
        topics:
          type:
          - array
          - 'null'
          items:
            type: string
            minLength: 1
            maxLength: 250
          description: Topics of the course (translated into the `language_code` of
            the course object)
          default: []
        instructor:
          type: string
          format: uuid
          description: ID of the instructor. This field is expandable.
        default_language_code:
          $ref: '#/components/schemas/LanguageEnum'
          description: Default language of the course (ISO 639-1 language code, e.g.
            `"de"`)
        is_archived:
          type: boolean
          description: |-
            `true`: course is archived

            `false`: course is not archived
          default: false
      required:
      - default_language_code
      - instructor
      - name
    Group:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: ID of the group
        name:
          type: string
          maxLength: 255
          description: Name of the group
        description:
          type:
          - string
          - 'null'
          description: Description of the group
        created_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time the group was created
        updated_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time the group was last updated
        dashboard_url:
          type: string
          format: uri
          readOnly: true
          description: URL of the group's detail view in the admin area of your Schulungstool
            account
      required:
      - created_at
      - dashboard_url
      - id
      - name
      - updated_at
    GroupRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Name of the group
        description:
          type:
          - string
          - 'null'
          description: Description of the group
          default: ''
      required:
      - name
    LanguageEnum:
      enum:
      - en
      - de
      - cs
      - pl
      - hr
      - fr
      - ro
      - it
      - el
      - nl
      - tr
      - ru
      - sk
      - sl
      - uk
      - hu
      - es
      - zh-hans
      - ja
      - ar
      - pt
      - sq
      - sr
      - bg
      - fa
      - vi
      - ta
      - bs
      - hi
      - ur
      - tl
      - mk
      type: string
    PaginatedCourseCategoryList:
      type: object
      required:
      - count
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of results; a page contains at most `page_size`
            results (default 25).
        next:
          type:
          - string
          - 'null'
          format: uri
        previous:
          type:
          - string
          - 'null'
          format: uri
        results:
          type: array
          items:
            $ref: '#/components/schemas/CourseCategory'
    PaginatedCourseList:
      type: object
      required:
      - count
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of results; a page contains at most `page_size`
            results (default 25).
        next:
          type:
          - string
          - 'null'
          format: uri
        previous:
          type:
          - string
          - 'null'
          format: uri
        results:
          type: array
          items:
            $ref: '#/components/schemas/Course'
    PaginatedCourseRatingList:
      type: object
      required:
      - count
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of results; a page contains at most `page_size`
            results (default 25).
        next:
          type:
          - string
          - 'null'
          format: uri
        previous:
          type:
          - string
          - 'null'
          format: uri
        results:
          type: array
          items:
            $ref: '#/components/schemas/CourseRating'
    PaginatedGroupList:
      type: object
      required:
      - count
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of results; a page contains at most `page_size`
            results (default 25).
        next:
          type:
          - string
          - 'null'
          format: uri
        previous:
          type:
          - string
          - 'null'
          format: uri
        results:
          type: array
          items:
            $ref: '#/components/schemas/Group'
    PaginatedParticipationList:
      type: object
      required:
      - count
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of results; a page contains at most `page_size`
            results (default 25).
        next:
          type:
          - string
          - 'null'
          format: uri
        previous:
          type:
          - string
          - 'null'
          format: uri
        results:
          type: array
          items:
            $ref: '#/components/schemas/Participation'
    PaginatedUserList:
      type: object
      required:
      - count
      - results
      properties:
        count:
          type: integer
          example: 123
          description: Total number of results; a page contains at most `page_size`
            results (default 25).
        next:
          type:
          - string
          - 'null'
          format: uri
        previous:
          type:
          - string
          - 'null'
          format: uri
        results:
          type: array
          items:
            $ref: '#/components/schemas/User'
    Participation:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: ID of the participation
        user:
          type: string
          format: uuid
          description: ID of the participation's user. This field is expandable.
        course:
          type: string
          format: uuid
          description: ID of the participation's course. This field is expandable.
        due_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Due date of the participation (ISO 8601 date format: *YYYY-MM-DD*,
            e.g. `"2026-12-31"`)'
        completed_at:
          type:
          - string
          - 'null'
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Completion date of the participation
        status:
          allOf:
          - $ref: '#/components/schemas/StatusEnum'
          readOnly: true
          description: |-
            Status of the participation

            `done`: participation is completed

            `pending`: participation is open
        created_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time the participation was created
        updated_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time the participation was last updated
        learn_url:
          type: string
          format: uri
          readOnly: true
          description: URL of the participation in the user area, where the participation
            is completed
        dashboard_url:
          type: string
          format: uri
          readOnly: true
          description: URL of the participation's detail view in the admin area of
            your Schulungstool account
      required:
      - completed_at
      - course
      - created_at
      - dashboard_url
      - due_date
      - id
      - learn_url
      - status
      - updated_at
      - user
    ParticipationRequest:
      type: object
      properties:
        user:
          type: string
          format: uuid
          description: ID of the participation's user. This field is expandable.
        course:
          type: string
          format: uuid
          description: ID of the participation's course. This field is expandable.
        due_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Due date of the participation (ISO 8601 date format: *YYYY-MM-DD*,
            e.g. `"2026-12-31"`)'
        send_email_notification:
          type: boolean
          writeOnly: true
          default: false
          description: |-
            `true`: the user is notified about the new participation by email, just like when a course is assigned in the admin area

            `false`: no email is sent

            Users without an email address and users with a pending invitation receive no email; the participation is still created. For deactivated users, no participation can be created regardless of this parameter.
        email_scheduled_at:
          type:
          - string
          - 'null'
          format: date-time
          writeOnly: true
          description: Time at which the email is sent. The time must be in the future.
            Without a value, the email is sent immediately. Only allowed when `send_email_notification`
            is set to `true`.
        email_note:
          type: string
          writeOnly: true
          maxLength: 2000
          description: Personal message included in the email (at most 2000 characters).
            Line breaks (`\n`) are allowed and kept in the email. Only allowed when
            `send_email_notification` is set to `true`.
      required:
      - course
      - due_date
      - user
    PatchedCourseCategoryRequest:
      type: object
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 50
          description: Title of the course category
    PatchedCourseRequest:
      type: object
      properties:
        category:
          type:
          - string
          - 'null'
          format: uuid
          description: ID of the course category. This field is expandable.
        name:
          type: string
          minLength: 1
          maxLength: 250
          description: Name of the course (translated into the `language_code` of
            the course object)
        description:
          type: string
          description: Description of the course (translated into the `language_code`
            of the course object)
        topics:
          type:
          - array
          - 'null'
          items:
            type: string
            minLength: 1
            maxLength: 250
          description: Topics of the course (translated into the `language_code` of
            the course object)
        instructor:
          type: string
          format: uuid
          description: ID of the instructor. This field is expandable.
        default_language_code:
          $ref: '#/components/schemas/LanguageEnum'
          description: Default language of the course (ISO 639-1 language code, e.g.
            `"de"`)
        is_archived:
          type: boolean
          description: |-
            `true`: course is archived

            `false`: course is not archived
    PatchedGroupRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Name of the group
        description:
          type:
          - string
          - 'null'
          description: Description of the group
    PatchedParticipationRequest:
      type: object
      properties:
        due_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Due date of the participation (ISO 8601 date format: *YYYY-MM-DD*,
            e.g. `"2026-12-31"`)'
    PatchedUserRequest:
      type: object
      properties:
        username:
          type: string
          minLength: 1
          description: Username of the user
          pattern: ^[\w.@+-]+$
          maxLength: 150
        first_name:
          type: string
          maxLength: 150
          description: First name of the user
        last_name:
          type: string
          maxLength: 150
          description: Last name of the user
        password:
          type: string
          writeOnly: true
          minLength: 1
          maxLength: 128
          description: Password of the user
        requires_password_change:
          type: boolean
          description: |-
            `true`: the user must set a new password before continuing to use Schulungstool (at the next login, or immediately for an existing session)

            `false`: no password change required
        email:
          oneOf:
          - type:
            - string
            - 'null'
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: Email address of the user, used for login and notifications
        notification_email:
          oneOf:
          - type: string
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: Additional email address of the user, used for notifications
        staff_number:
          type: string
          maxLength: 50
          description: Staff number of the user
        description:
          type: string
          description: Description of the user
        birth_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Date of birth of the user (ISO 8601 date format: *YYYY-MM-DD*,
            e.g. `"1990-01-19"`)'
        birth_place:
          type: string
          maxLength: 150
          description: Place of birth of the user
        organization:
          type: string
          maxLength: 250
          description: Organization of the user
        department:
          type: string
          maxLength: 150
          description: Department of the user
        job_title:
          type: string
          maxLength: 150
          description: Job title of the user
        street_address:
          type: string
          maxLength: 250
          description: Street and number of the user
        postal_code:
          type: string
          maxLength: 10
          description: Postal code of the user
        city:
          type: string
          maxLength: 150
          description: City of the user
        country:
          oneOf:
          - $ref: '#/components/schemas/CountryEnum'
          - $ref: '#/components/schemas/BlankEnum'
          description: Country of the user
        phone:
          type: string
          maxLength: 128
          description: Phone number of the user
        language:
          allOf:
          - $ref: '#/components/schemas/LanguageEnum'
          description: Language of the user (ISO 639-1 language code, e.g. `"de"`)
        is_active:
          type: boolean
          default: true
          description: |-
            `true`: user is activated

            `false`: user is deactivated
    RatingEnum:
      enum:
      - 1
      - 2
      - 3
      - 4
      - 5
      type: integer
    RoleEnum:
      enum:
      - user
      - manager
      - billing_manager
      - admin
      type: string
    StatusEnum:
      enum:
      - done
      - pending
      type: string
    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: ID of the user
        username:
          type: string
          description: Username of the user
          pattern: ^[\w.@+-]+$
          maxLength: 150
        first_name:
          type: string
          maxLength: 150
          description: First name of the user
        last_name:
          type: string
          maxLength: 150
          description: Last name of the user
        requires_password_change:
          type: boolean
          description: |-
            `true`: the user must set a new password before continuing to use Schulungstool (at the next login, or immediately for an existing session)

            `false`: no password change required
        email:
          oneOf:
          - type:
            - string
            - 'null'
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: Email address of the user, used for login and notifications
        notification_email:
          oneOf:
          - type: string
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: Additional email address of the user, used for notifications
        staff_number:
          type: string
          maxLength: 50
          description: Staff number of the user
        description:
          type: string
          description: Description of the user
        birth_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Date of birth of the user (ISO 8601 date format: *YYYY-MM-DD*,
            e.g. `"1990-01-19"`)'
        birth_place:
          type: string
          maxLength: 150
          description: Place of birth of the user
        organization:
          type: string
          maxLength: 250
          description: Organization of the user
        department:
          type: string
          maxLength: 150
          description: Department of the user
        job_title:
          type: string
          maxLength: 150
          description: Job title of the user
        street_address:
          type: string
          maxLength: 250
          description: Street and number of the user
        postal_code:
          type: string
          maxLength: 10
          description: Postal code of the user
        city:
          type: string
          maxLength: 150
          description: City of the user
        country:
          oneOf:
          - $ref: '#/components/schemas/CountryEnum'
          - $ref: '#/components/schemas/BlankEnum'
          description: Country of the user
        phone:
          type: string
          maxLength: 128
          description: Phone number of the user
        language:
          allOf:
          - $ref: '#/components/schemas/LanguageEnum'
          description: Language of the user (ISO 639-1 language code, e.g. `"de"`)
        last_active:
          type:
          - string
          - 'null'
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Last activity of the user
        role:
          allOf:
          - $ref: '#/components/schemas/RoleEnum'
          readOnly: true
          description: |-
            Role of the user

            `user`: user

            `manager`: manager

            `billing_manager`: billing manager

            `admin`: administrator
        is_active:
          type: boolean
          default: true
          description: |-
            `true`: user is activated

            `false`: user is deactivated
        deactivated_at:
          type:
          - string
          - 'null'
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time of deactivation; `null` while the user is active.
        created_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time the user was created
        updated_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Time the user was last updated
        dashboard_url:
          type: string
          format: uri
          readOnly: true
          description: URL of the user's detail view in the admin area of your Schulungstool
            account
      required:
      - created_at
      - dashboard_url
      - deactivated_at
      - first_name
      - id
      - last_active
      - last_name
      - role
      - updated_at
      - username
    UserInviteRequest:
      type: object
      properties:
        email:
          oneOf:
          - type:
            - string
            - 'null'
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: Email address of the user being invited
        inviter:
          type: string
          format: uuid
          description: ID of the user who invites the new user
        language:
          allOf:
          - $ref: '#/components/schemas/LanguageEnum'
          description: Language of the invitation email (ISO 639-1 language code,
            e.g. `"de"`)
          default: de
      required:
      - email
      - inviter
    UserRequest:
      type: object
      properties:
        username:
          type: string
          minLength: 1
          description: Username of the user
          pattern: ^[\w.@+-]+$
          maxLength: 150
        first_name:
          type: string
          maxLength: 150
          description: First name of the user
        last_name:
          type: string
          maxLength: 150
          description: Last name of the user
        password:
          type: string
          writeOnly: true
          minLength: 1
          maxLength: 128
          description: Password of the user
        requires_password_change:
          type: boolean
          description: |-
            `true`: the user must set a new password before continuing to use Schulungstool (at the next login, or immediately for an existing session)

            `false`: no password change required
          default: false
        email:
          oneOf:
          - type:
            - string
            - 'null'
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: Email address of the user, used for login and notifications
          default: null
        notification_email:
          oneOf:
          - type: string
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: Additional email address of the user, used for notifications
          default: ''
        staff_number:
          type: string
          maxLength: 50
          description: Staff number of the user
          default: ''
        description:
          type: string
          description: Description of the user
          default: ''
        birth_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Date of birth of the user (ISO 8601 date format: *YYYY-MM-DD*,
            e.g. `"1990-01-19"`)'
          default: null
        birth_place:
          type: string
          maxLength: 150
          description: Place of birth of the user
          default: ''
        organization:
          type: string
          maxLength: 250
          description: Organization of the user
          default: ''
        department:
          type: string
          maxLength: 150
          description: Department of the user
          default: ''
        job_title:
          type: string
          maxLength: 150
          description: Job title of the user
          default: ''
        street_address:
          type: string
          maxLength: 250
          description: Street and number of the user
          default: ''
        postal_code:
          type: string
          maxLength: 10
          description: Postal code of the user
          default: ''
        city:
          type: string
          maxLength: 150
          description: City of the user
          default: ''
        country:
          oneOf:
          - $ref: '#/components/schemas/CountryEnum'
          - $ref: '#/components/schemas/BlankEnum'
          description: Country of the user
          default: ''
        phone:
          type: string
          maxLength: 128
          description: Phone number of the user
          default: ''
        language:
          allOf:
          - $ref: '#/components/schemas/LanguageEnum'
          description: Language of the user (ISO 639-1 language code, e.g. `"de"`)
          default: de
        is_active:
          type: boolean
          default: true
          description: |-
            `true`: user is activated

            `false`: user is deactivated
      required:
      - first_name
      - last_name
      - password
      - username
    Error:
      type: object
      required:
      - error
      properties:
        error:
          type: object
          required:
          - type
          - message
          properties:
            type:
              type: string
              x-extensible-enum:
              - ValidationError
              - ParseError
              - AuthenticationFailed
              - NotAuthenticated
              - PermissionDenied
              - NotFound
              - MethodNotAllowed
              - NotAcceptable
              - UnsupportedMediaType
              - Throttled
              - IdempotencyKeyInvalidError
              - IdempotencyKeyReuseError
              - IdempotencyKeyInUseError
              - InternalServerError
              - MissingScope
            message:
              type: string
            request_id:
              type: string
              description: Unique ID of this request. Include it in support inquiries
                so we can locate the request in our logs.
            required_scope:
              type: string
              description: Only present for `MissingScope` errors.
            doc_url:
              type: string
              description: Only present for `MissingScope` errors.
            field_errors:
              type: object
              additionalProperties:
                type: array
                items:
                  type: string
              description: Only for `ValidationError`.
            non_field_errors:
              type: array
              items:
                type: string
              description: Only for `ValidationError`.
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      description: |-
        API key from *Settings > Advanced settings > Developer options*. Header `Authorization: Token <API key>`; `Bearer <API key>` is also accepted.

        Each key carries access scopes that control which endpoints it may call; every operation below names its required scope. A key without the required scope receives `403` with `error.type: "MissingScope"` and the missing scope in `error.required_scope`. `GET /v1/me/` returns the scopes of the key in use. Details: [access scopes guide](https://docs.api.schulungstool.de/guides/authentication/#access-scopes).

        | Resource | Scopes |
        |---|---|
        | Users | `users:read`, `users:write` |
        | Groups | `groups:read`, `groups:write` |
        | Courses | `courses:read`, `courses:write` |
        | Course categories | `course-categories:read`, `course-categories:write` |
        | Course ratings | `course-ratings:read` |
        | Participations | `participations:read`, `participations:write` |
        | Login links | `login-links:write` |
servers:
- url: https://api.schulungstool.de
  description: Production
x-tagGroups:
- name: General
  tags:
  - API key
- name: Course management
  tags:
  - Courses
  - Course categories
  - Course ratings
  - Participations
- name: User management
  tags:
  - Users
  - Groups
- name: Webhooks
  tags:
  - Webhooks
webhooks:
  participation.created:
    post:
      operationId: webhook_participation_created
      summary: Course assignment created
      description: 'Sent when a course assignment is created: by an administrator,
        by a recurring training, via import, or via the API. Fetch the current state
        via `GET /v1/participations/{id}/`.'
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: The event id, identical across all delivery attempts (same value
          as `id` in the body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix timestamp (seconds) of this delivery attempt; part of the
          signed content.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signature of this delivery per the [Standard Webhooks](https://www.standardwebhooks.com/)
          spec: `v1,<Base64>`. During a secret rotation the header carries several
          space-separated signatures; any one valid signature is sufficient.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - id
              - type
              - occurred_at
              - api_version
              - tenant
              - tenant_id
              - data
              properties:
                id:
                  type: string
                  description: 'Unique event id (`msg_...`). Identical across all
                    delivery attempts of this event: use it to process events idempotently.'
                type:
                  type: string
                  const: participation.created
                  description: The event type. Receivers must ignore unknown types,
                    so new types can be added without breaking your integration.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'When the event occurred: RFC 3339 in UTC with exactly
                    six fractional digits and `Z` suffix, so timestamps sort lexicographically.'
                api_version:
                  type: string
                  const: v1
                  description: Version of the data contract (currently `v1`).
                tenant:
                  type: string
                  description: Domain of the workspace the event belongs to, e.g.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stable id of the workspace. Useful when one receiver
                    serves several workspaces.
                data:
                  type: object
                  required:
                  - id
                  - user
                  - course
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'Id of the course assignment: `GET /v1/participations/{id}/`.'
                    user:
                      type: string
                      format: uuid
                      description: 'Id of the assigned user: `GET /v1/users/{id}/`.'
                    course:
                      type: string
                      format: uuid
                      description: 'Id of the course: `GET /v1/courses/{id}/`.'
                  description: 'The event payload: ids only. Fetch the current object
                    state via the API; receivers must ignore unknown fields.'
            example:
              id: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
              type: participation.created
              occurred_at: '2026-10-17T14:00:00.123456Z'
              api_version: v1
              tenant: ihre-firma.schulungstool.de
              tenant_id: 018c2a4e-9a6c-4e0d-8b8f-4c5d6e7f8a9b
              data:
                id: 018c2a4e-6d3f-4b7a-9e5c-1f2a3b4c5d6e
                user: 018c2a4e-7e4a-4c8b-8f6d-2a3b4c5d6e7f
                course: 018c2a4e-8f5b-4d9c-9a7e-3b4c5d6e7f8a
      responses:
        2XX:
          description: Any 2xx status acknowledges the delivery. Every other response,
            including redirects, counts as a failure and the delivery is retried with
            exponential backoff.
  participation.completed:
    post:
      operationId: webhook_participation_completed
      summary: Course assignment completed
      description: Sent each time a course assignment is marked as completed, regardless
        of who completed it (learner, administrator, or API). Fetch the current state
        via `GET /v1/participations/{id}/`.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: The event id, identical across all delivery attempts (same value
          as `id` in the body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix timestamp (seconds) of this delivery attempt; part of the
          signed content.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signature of this delivery per the [Standard Webhooks](https://www.standardwebhooks.com/)
          spec: `v1,<Base64>`. During a secret rotation the header carries several
          space-separated signatures; any one valid signature is sufficient.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - id
              - type
              - occurred_at
              - api_version
              - tenant
              - tenant_id
              - data
              properties:
                id:
                  type: string
                  description: 'Unique event id (`msg_...`). Identical across all
                    delivery attempts of this event: use it to process events idempotently.'
                type:
                  type: string
                  const: participation.completed
                  description: The event type. Receivers must ignore unknown types,
                    so new types can be added without breaking your integration.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'When the event occurred: RFC 3339 in UTC with exactly
                    six fractional digits and `Z` suffix, so timestamps sort lexicographically.'
                api_version:
                  type: string
                  const: v1
                  description: Version of the data contract (currently `v1`).
                tenant:
                  type: string
                  description: Domain of the workspace the event belongs to, e.g.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stable id of the workspace. Useful when one receiver
                    serves several workspaces.
                data:
                  type: object
                  required:
                  - id
                  - user
                  - course
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'Id of the course assignment: `GET /v1/participations/{id}/`.'
                    user:
                      type: string
                      format: uuid
                      description: 'Id of the assigned user: `GET /v1/users/{id}/`.'
                    course:
                      type: string
                      format: uuid
                      description: 'Id of the course: `GET /v1/courses/{id}/`.'
                  description: 'The event payload: ids only. Fetch the current object
                    state via the API; receivers must ignore unknown fields.'
            example:
              id: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
              type: participation.completed
              occurred_at: '2026-10-17T14:00:00.123456Z'
              api_version: v1
              tenant: ihre-firma.schulungstool.de
              tenant_id: 018c2a4e-9a6c-4e0d-8b8f-4c5d6e7f8a9b
              data:
                id: 018c2a4e-6d3f-4b7a-9e5c-1f2a3b4c5d6e
                user: 018c2a4e-7e4a-4c8b-8f6d-2a3b4c5d6e7f
                course: 018c2a4e-8f5b-4d9c-9a7e-3b4c5d6e7f8a
      responses:
        2XX:
          description: Any 2xx status acknowledges the delivery. Every other response,
            including redirects, counts as a failure and the delivery is retried with
            exponential backoff.
  participation.certificate_created:
    post:
      operationId: webhook_participation_certificate_created
      summary: Certificate created
      description: Sent when the certificate for a completed course assignment has
        been generated. Download it via `GET /v1/participations/{id}/certificate/`.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: The event id, identical across all delivery attempts (same value
          as `id` in the body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix timestamp (seconds) of this delivery attempt; part of the
          signed content.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signature of this delivery per the [Standard Webhooks](https://www.standardwebhooks.com/)
          spec: `v1,<Base64>`. During a secret rotation the header carries several
          space-separated signatures; any one valid signature is sufficient.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - id
              - type
              - occurred_at
              - api_version
              - tenant
              - tenant_id
              - data
              properties:
                id:
                  type: string
                  description: 'Unique event id (`msg_...`). Identical across all
                    delivery attempts of this event: use it to process events idempotently.'
                type:
                  type: string
                  const: participation.certificate_created
                  description: The event type. Receivers must ignore unknown types,
                    so new types can be added without breaking your integration.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'When the event occurred: RFC 3339 in UTC with exactly
                    six fractional digits and `Z` suffix, so timestamps sort lexicographically.'
                api_version:
                  type: string
                  const: v1
                  description: Version of the data contract (currently `v1`).
                tenant:
                  type: string
                  description: Domain of the workspace the event belongs to, e.g.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stable id of the workspace. Useful when one receiver
                    serves several workspaces.
                data:
                  type: object
                  required:
                  - id
                  - user
                  - course
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'Id of the course assignment: `GET /v1/participations/{id}/`.'
                    user:
                      type: string
                      format: uuid
                      description: 'Id of the assigned user: `GET /v1/users/{id}/`.'
                    course:
                      type: string
                      format: uuid
                      description: 'Id of the course: `GET /v1/courses/{id}/`.'
                  description: 'The event payload: ids only. Fetch the current object
                    state via the API; receivers must ignore unknown fields.'
            example:
              id: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
              type: participation.certificate_created
              occurred_at: '2026-10-17T14:00:00.123456Z'
              api_version: v1
              tenant: ihre-firma.schulungstool.de
              tenant_id: 018c2a4e-9a6c-4e0d-8b8f-4c5d6e7f8a9b
              data:
                id: 018c2a4e-6d3f-4b7a-9e5c-1f2a3b4c5d6e
                user: 018c2a4e-7e4a-4c8b-8f6d-2a3b4c5d6e7f
                course: 018c2a4e-8f5b-4d9c-9a7e-3b4c5d6e7f8a
      responses:
        2XX:
          description: Any 2xx status acknowledges the delivery. Every other response,
            including redirects, counts as a failure and the delivery is retried with
            exponential backoff.
  participation.deleted:
    post:
      operationId: webhook_participation_deleted
      summary: Course assignment deleted
      description: Sent when a course assignment is moved to the trash, including
        assignments removed because their user was deleted. `data` carries only the
        id and the deletion time; the object cannot be fetched anymore.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: The event id, identical across all delivery attempts (same value
          as `id` in the body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix timestamp (seconds) of this delivery attempt; part of the
          signed content.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signature of this delivery per the [Standard Webhooks](https://www.standardwebhooks.com/)
          spec: `v1,<Base64>`. During a secret rotation the header carries several
          space-separated signatures; any one valid signature is sufficient.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - id
              - type
              - occurred_at
              - api_version
              - tenant
              - tenant_id
              - data
              properties:
                id:
                  type: string
                  description: 'Unique event id (`msg_...`). Identical across all
                    delivery attempts of this event: use it to process events idempotently.'
                type:
                  type: string
                  const: participation.deleted
                  description: The event type. Receivers must ignore unknown types,
                    so new types can be added without breaking your integration.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'When the event occurred: RFC 3339 in UTC with exactly
                    six fractional digits and `Z` suffix, so timestamps sort lexicographically.'
                api_version:
                  type: string
                  const: v1
                  description: Version of the data contract (currently `v1`).
                tenant:
                  type: string
                  description: Domain of the workspace the event belongs to, e.g.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stable id of the workspace. Useful when one receiver
                    serves several workspaces.
                data:
                  type: object
                  required:
                  - id
                  - deleted_at
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: Id of the deleted object.
                    deleted_at:
                      type: string
                      pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
                      description: 'Deletion time in the v1 time format: local time,
                        seconds precision, no offset.'
                  description: 'The event payload: ids only. Fetch the current object
                    state via the API; receivers must ignore unknown fields.'
            example:
              id: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
              type: participation.deleted
              occurred_at: '2026-10-17T14:00:00.123456Z'
              api_version: v1
              tenant: ihre-firma.schulungstool.de
              tenant_id: 018c2a4e-9a6c-4e0d-8b8f-4c5d6e7f8a9b
              data:
                id: 018c2a4e-6d3f-4b7a-9e5c-1f2a3b4c5d6e
                deleted_at: '2026-10-17T14:00:00'
      responses:
        2XX:
          description: Any 2xx status acknowledges the delivery. Every other response,
            including redirects, counts as a failure and the delivery is retried with
            exponential backoff.
  user.created:
    post:
      operationId: webhook_user_created
      summary: User created
      description: 'Sent when a user account is created: by an administrator, via
        import, via self-signup, or via the API. Fetch the current state via `GET
        /v1/users/{id}/`.'
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: The event id, identical across all delivery attempts (same value
          as `id` in the body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix timestamp (seconds) of this delivery attempt; part of the
          signed content.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signature of this delivery per the [Standard Webhooks](https://www.standardwebhooks.com/)
          spec: `v1,<Base64>`. During a secret rotation the header carries several
          space-separated signatures; any one valid signature is sufficient.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - id
              - type
              - occurred_at
              - api_version
              - tenant
              - tenant_id
              - data
              properties:
                id:
                  type: string
                  description: 'Unique event id (`msg_...`). Identical across all
                    delivery attempts of this event: use it to process events idempotently.'
                type:
                  type: string
                  const: user.created
                  description: The event type. Receivers must ignore unknown types,
                    so new types can be added without breaking your integration.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'When the event occurred: RFC 3339 in UTC with exactly
                    six fractional digits and `Z` suffix, so timestamps sort lexicographically.'
                api_version:
                  type: string
                  const: v1
                  description: Version of the data contract (currently `v1`).
                tenant:
                  type: string
                  description: Domain of the workspace the event belongs to, e.g.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stable id of the workspace. Useful when one receiver
                    serves several workspaces.
                data:
                  type: object
                  required:
                  - id
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'Id of the user: `GET /v1/users/{id}/`.'
                  description: 'The event payload: ids only. Fetch the current object
                    state via the API; receivers must ignore unknown fields.'
            example:
              id: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
              type: user.created
              occurred_at: '2026-10-17T14:00:00.123456Z'
              api_version: v1
              tenant: ihre-firma.schulungstool.de
              tenant_id: 018c2a4e-9a6c-4e0d-8b8f-4c5d6e7f8a9b
              data:
                id: 018c2a4e-7e4a-4c8b-8f6d-2a3b4c5d6e7f
      responses:
        2XX:
          description: Any 2xx status acknowledges the delivery. Every other response,
            including redirects, counts as a failure and the delivery is retried with
            exponential backoff.
  user.activated:
    post:
      operationId: webhook_user_activated
      summary: User activated
      description: Sent when a deactivated user account is activated again. Fetch
        the current state via `GET /v1/users/{id}/`.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: The event id, identical across all delivery attempts (same value
          as `id` in the body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix timestamp (seconds) of this delivery attempt; part of the
          signed content.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signature of this delivery per the [Standard Webhooks](https://www.standardwebhooks.com/)
          spec: `v1,<Base64>`. During a secret rotation the header carries several
          space-separated signatures; any one valid signature is sufficient.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - id
              - type
              - occurred_at
              - api_version
              - tenant
              - tenant_id
              - data
              properties:
                id:
                  type: string
                  description: 'Unique event id (`msg_...`). Identical across all
                    delivery attempts of this event: use it to process events idempotently.'
                type:
                  type: string
                  const: user.activated
                  description: The event type. Receivers must ignore unknown types,
                    so new types can be added without breaking your integration.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'When the event occurred: RFC 3339 in UTC with exactly
                    six fractional digits and `Z` suffix, so timestamps sort lexicographically.'
                api_version:
                  type: string
                  const: v1
                  description: Version of the data contract (currently `v1`).
                tenant:
                  type: string
                  description: Domain of the workspace the event belongs to, e.g.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stable id of the workspace. Useful when one receiver
                    serves several workspaces.
                data:
                  type: object
                  required:
                  - id
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'Id of the user: `GET /v1/users/{id}/`.'
                  description: 'The event payload: ids only. Fetch the current object
                    state via the API; receivers must ignore unknown fields.'
            example:
              id: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
              type: user.activated
              occurred_at: '2026-10-17T14:00:00.123456Z'
              api_version: v1
              tenant: ihre-firma.schulungstool.de
              tenant_id: 018c2a4e-9a6c-4e0d-8b8f-4c5d6e7f8a9b
              data:
                id: 018c2a4e-7e4a-4c8b-8f6d-2a3b4c5d6e7f
      responses:
        2XX:
          description: Any 2xx status acknowledges the delivery. Every other response,
            including redirects, counts as a failure and the delivery is retried with
            exponential backoff.
  user.deactivated:
    post:
      operationId: webhook_user_deactivated
      summary: User deactivated
      description: Sent when a user account is deactivated. Fetch the current state
        via `GET /v1/users/{id}/`.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: The event id, identical across all delivery attempts (same value
          as `id` in the body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix timestamp (seconds) of this delivery attempt; part of the
          signed content.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signature of this delivery per the [Standard Webhooks](https://www.standardwebhooks.com/)
          spec: `v1,<Base64>`. During a secret rotation the header carries several
          space-separated signatures; any one valid signature is sufficient.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - id
              - type
              - occurred_at
              - api_version
              - tenant
              - tenant_id
              - data
              properties:
                id:
                  type: string
                  description: 'Unique event id (`msg_...`). Identical across all
                    delivery attempts of this event: use it to process events idempotently.'
                type:
                  type: string
                  const: user.deactivated
                  description: The event type. Receivers must ignore unknown types,
                    so new types can be added without breaking your integration.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'When the event occurred: RFC 3339 in UTC with exactly
                    six fractional digits and `Z` suffix, so timestamps sort lexicographically.'
                api_version:
                  type: string
                  const: v1
                  description: Version of the data contract (currently `v1`).
                tenant:
                  type: string
                  description: Domain of the workspace the event belongs to, e.g.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stable id of the workspace. Useful when one receiver
                    serves several workspaces.
                data:
                  type: object
                  required:
                  - id
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'Id of the user: `GET /v1/users/{id}/`.'
                  description: 'The event payload: ids only. Fetch the current object
                    state via the API; receivers must ignore unknown fields.'
            example:
              id: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
              type: user.deactivated
              occurred_at: '2026-10-17T14:00:00.123456Z'
              api_version: v1
              tenant: ihre-firma.schulungstool.de
              tenant_id: 018c2a4e-9a6c-4e0d-8b8f-4c5d6e7f8a9b
              data:
                id: 018c2a4e-7e4a-4c8b-8f6d-2a3b4c5d6e7f
      responses:
        2XX:
          description: Any 2xx status acknowledges the delivery. Every other response,
            including redirects, counts as a failure and the delivery is retried with
            exponential backoff.
  user.deleted:
    post:
      operationId: webhook_user_deleted
      summary: User deleted
      description: Sent when a user account is moved to the trash. Course assignments
        removed along with the user emit their own `participation.deleted` events.
        `data` carries only the id and the deletion time.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: The event id, identical across all delivery attempts (same value
          as `id` in the body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix timestamp (seconds) of this delivery attempt; part of the
          signed content.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signature of this delivery per the [Standard Webhooks](https://www.standardwebhooks.com/)
          spec: `v1,<Base64>`. During a secret rotation the header carries several
          space-separated signatures; any one valid signature is sufficient.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - id
              - type
              - occurred_at
              - api_version
              - tenant
              - tenant_id
              - data
              properties:
                id:
                  type: string
                  description: 'Unique event id (`msg_...`). Identical across all
                    delivery attempts of this event: use it to process events idempotently.'
                type:
                  type: string
                  const: user.deleted
                  description: The event type. Receivers must ignore unknown types,
                    so new types can be added without breaking your integration.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'When the event occurred: RFC 3339 in UTC with exactly
                    six fractional digits and `Z` suffix, so timestamps sort lexicographically.'
                api_version:
                  type: string
                  const: v1
                  description: Version of the data contract (currently `v1`).
                tenant:
                  type: string
                  description: Domain of the workspace the event belongs to, e.g.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stable id of the workspace. Useful when one receiver
                    serves several workspaces.
                data:
                  type: object
                  required:
                  - id
                  - deleted_at
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: Id of the deleted object.
                    deleted_at:
                      type: string
                      pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
                      description: 'Deletion time in the v1 time format: local time,
                        seconds precision, no offset.'
                  description: 'The event payload: ids only. Fetch the current object
                    state via the API; receivers must ignore unknown fields.'
            example:
              id: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
              type: user.deleted
              occurred_at: '2026-10-17T14:00:00.123456Z'
              api_version: v1
              tenant: ihre-firma.schulungstool.de
              tenant_id: 018c2a4e-9a6c-4e0d-8b8f-4c5d6e7f8a9b
              data:
                id: 018c2a4e-7e4a-4c8b-8f6d-2a3b4c5d6e7f
                deleted_at: '2026-10-17T14:00:00'
      responses:
        2XX:
          description: Any 2xx status acknowledges the delivery. Every other response,
            including redirects, counts as a failure and the delivery is retried with
            exponential backoff.
  ping:
    post:
      operationId: webhook_ping
      summary: Test event (ping)
      description: Sent only via *Send test event* in the developer options. `data`
        is always empty. Test events of the other types use the example values shown
        in this reference.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: The event id, identical across all delivery attempts (same value
          as `id` in the body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix timestamp (seconds) of this delivery attempt; part of the
          signed content.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signature of this delivery per the [Standard Webhooks](https://www.standardwebhooks.com/)
          spec: `v1,<Base64>`. During a secret rotation the header carries several
          space-separated signatures; any one valid signature is sufficient.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - id
              - type
              - occurred_at
              - api_version
              - tenant
              - tenant_id
              - data
              properties:
                id:
                  type: string
                  description: 'Unique event id (`msg_...`). Identical across all
                    delivery attempts of this event: use it to process events idempotently.'
                type:
                  type: string
                  const: ping
                  description: The event type. Receivers must ignore unknown types,
                    so new types can be added without breaking your integration.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'When the event occurred: RFC 3339 in UTC with exactly
                    six fractional digits and `Z` suffix, so timestamps sort lexicographically.'
                api_version:
                  type: string
                  const: v1
                  description: Version of the data contract (currently `v1`).
                tenant:
                  type: string
                  description: Domain of the workspace the event belongs to, e.g.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stable id of the workspace. Useful when one receiver
                    serves several workspaces.
                data:
                  type: object
                  description: Always empty.
                  properties: {}
            example:
              id: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
              type: ping
              occurred_at: '2026-10-17T14:00:00.123456Z'
              api_version: v1
              tenant: ihre-firma.schulungstool.de
              tenant_id: 018c2a4e-9a6c-4e0d-8b8f-4c5d6e7f8a9b
              data: {}
      responses:
        2XX:
          description: Any 2xx status acknowledges the delivery. Every other response,
            including redirects, counts as a failure and the delivery is retried with
            exponential backoff.
tags:
- name: Course categories
  description: Categories for structuring the course catalog.
- name: Course ratings
  description: Participants' ratings of courses.
- name: Courses
  description: Retrieve and update courses.
- name: Groups
  description: User groups and their members.
- name: API key
  description: The API key used for the request, including its access scopes.
- name: Participations
  description: Assignments of users to courses, including status and certificate.
- name: Users
  description: Manage, invite, and deactivate user accounts.
- name: Webhooks
  description: Webhooks deliver events about users and course assignments to your
    HTTPS endpoint as signed POST requests. Administrators configure endpoints in
    the admin area under *Settings → Advanced settings → Developer options → Webhooks*.
    How to receive and verify events is covered in the [webhooks guide](https://docs.api.schulungstool.de/guides/webhooks/).
