openapi: 3.1.0
info:
  title: Schulungstool API
  version: 1.0.0 (v1)
  description: REST-API für Benutzer, Gruppen, Kurse, Kursteilnahmen, Kursbewertungen
    und Kurskategorien.
paths:
  /v1/course-categories/:
    get:
      operationId: course_categories_list
      description: |-
        Benötigtes Zugriffsrecht: Kurskategorien – Lesen (`course-categories:read`).

        Dieser API-Endpunkt gibt eine Liste aller Kurskategorien zurück.
      parameters:
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Kurskategorieobjekts.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend.
        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: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id` und `title`
          eines Kurskategorieobjekts gesucht wird.
        schema:
          type: string
      - in: query
        name: title
        schema:
          type: string
        description: Ein Filter für das Feld `title` eines Kurskategorieobjekts.
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `updated_at` eines Kurskategorieobjekts:
          liefert nur Kurskategorien, die zum angegebenen Zeitpunkt oder später geändert
          wurden (ISO 8601; der Zeitpunkt selbst zählt mit). Zusammen mit `ordering=updated_at`
          eignet sich das für Delta-Abfragen statt wiederholter Vollabrufe.'
      tags:
      - Kurskategorien
      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: Allgemein
                  updated_at: '2026-01-23T13:40:23'
                - created_at: '2026-01-23T13:42:21'
                  id: 071b2638-3ab5-409f-aa59-60c35c1158b0
                  title: Brandschutz
                  updated_at: '2026-01-23T13:42:21'
                - created_at: '2026-01-23T13:41:51'
                  id: 7efd09ae-8a91-48c4-85bd-dd9bb604af9a
                  title: Erste Hilfe
                  updated_at: '2026-01-23T13:41:51'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kurskategorien auflisten
      x-required-scope: course-categories:read
    post:
      operationId: course_categories_create
      description: |-
        Benötigtes Zugriffsrecht: Kurskategorien – Lesen und Schreiben (`course-categories:write`).

        Dieser API-Endpunkt erstellt eine Kurskategorie.
      tags:
      - Kurskategorien
      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: Allgemein
                updated_at: '2026-01-23T13:40:23'
          description: ''
          headers:
            Idempotent-Replayed:
              schema:
                type: boolean
              description: '`true`, wenn diese Antwort die gespeicherte Antwort einer
                früheren Anfrage mit demselben `Idempotency-Key` ist; fehlt bei der
                Erstausführung.'
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '422':
          description: Der `Idempotency-Key` wurde bereits für eine andere Anfrage
            verwendet.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '409':
          description: Eine Anfrage mit demselben `Idempotency-Key` läuft noch. Wiederholen
            Sie die Anfrage nach der in `Retry-After` angegebenen Zeit.
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Macht die Anfrage sicher wiederholbar: Wird sie mit demselben
          Key erneut gesendet, liefert die API die gespeicherte Antwort der ersten
          erfolgreichen Ausführung, statt erneut auszuführen (24 Stunden lang). Fehlversuche
          verbrauchen den Key nicht. Verwenden Sie für jede neue Operation einen neuen
          Key (z. B. eine UUID), 1 bis 200 Zeichen.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Kurskategorie erstellen
      x-required-scope: course-categories:write
  /v1/course-categories/{uuid}/:
    get:
      operationId: course_categories_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Kurskategorien – Lesen (`course-categories:read`).

        Dieser API-Endpunkt gibt eine Kurskategorie zurück.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Kurskategorie.
      tags:
      - Kurskategorien
      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: Allgemein
                updated_at: '2026-01-23T13:40:23'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kurskategorie abrufen
      x-required-scope: course-categories:read
    patch:
      operationId: course_categories_partial_update
      description: |-
        Benötigtes Zugriffsrecht: Kurskategorien – Lesen und Schreiben (`course-categories:write`).

        Dieser API-Endpunkt bearbeitet eine Kurskategorie.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Kurskategorie.
      tags:
      - Kurskategorien
      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: Allgemein
                updated_at: '2026-02-01T12:30:10'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kurskategorie bearbeiten
      x-required-scope: course-categories:write
    delete:
      operationId: course_categories_destroy
      description: |-
        Benötigtes Zugriffsrecht: Kurskategorien – Lesen und Schreiben (`course-categories:write`).

        Dieser API-Endpunkt löscht eine Kurskategorie.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Kurskategorie.
      tags:
      - Kurskategorien
      security:
      - ApiKey: []
      responses:
        '204':
          description: Erfolg, keine Antwortdaten.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kurskategorie löschen
      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: Ein Filter für das Feld `course` eines Kursbewertungsobjekts.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
        description: Felder, die als vollständiges Objekt statt als ID ausgeliefert
          werden.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Kursbewertungsobjekts.
      - 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: Ein Filter für das Feld `language_code` eines Kursbewertungsobjekts.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend.
        schema:
          type: array
          items:
            type: string
            enum:
            - rating
            - -rating
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          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: Ein Filter für das Feld `rating` eines Kursbewertungsobjekts.
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id`, `course` (`name`
          des zugehörigen Kursobjekts) und `comment` eines Kursbewertungsobjekts gesucht
          wird.
        schema:
          type: string
      tags:
      - Kursbewertungen
      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: Der Kurs hat mir gut gefallen.
                  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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kursbewertungen auflisten
      description: |-
        Benötigtes Zugriffsrecht: Kursbewertungen – Lesen (`course-ratings:read`).

        Dieser API-Endpunkt gibt eine Liste aller Kursbewertungen zurück. Bewertungen sind anonym: Die Bewertungen eines Kurses sind erst enthalten, sobald mindestens fünf für ihn abgegeben wurden.
      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: Felder, die als vollständiges Objekt statt als ID ausgeliefert
          werden.
        explode: false
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Kursbewertung.
      tags:
      - Kursbewertungen
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CourseRating'
              example:
                comment: Der Kurs hat mir gut gefallen.
                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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kursbewertung abrufen
      description: |-
        Benötigtes Zugriffsrecht: Kursbewertungen – Lesen (`course-ratings:read`).

        Dieser API-Endpunkt gibt eine Kursbewertung zurück. Bewertungen sind anonym: Eine Bewertung ist erst abrufbar, sobald mindestens fünf für ihren Kurs abgegeben wurden.
      x-required-scope: course-ratings:read
  /v1/courses/:
    get:
      operationId: courses_list
      description: |-
        Benötigtes Zugriffsrecht: Kurse – Lesen (`courses:read`).

        Dieser API-Endpunkt gibt eine Liste aller Kurse zurück.
      parameters:
      - in: query
        name: category
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `category` eines Kursobjekts.
      - in: query
        name: description
        schema:
          type: string
        description: Ein Filter für das Feld `description` eines Kursobjekts.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - category
            - instructor
        description: Felder, die als vollständiges Objekt statt als ID ausgeliefert
          werden.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Kursobjekts.
      - in: query
        name: instructor
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `instructor` eines Kursobjekts.
      - in: query
        name: is_archived
        schema:
          type: boolean
        description: Ein Filter für das Feld `is_archived` eines Kursobjekts.
      - 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: Sprache der Kursinhalte; fehlt sie im Kurs, gilt die Standardsprache
          des Kurses.
      - in: query
        name: name
        schema:
          type: string
        description: Ein Filter für das Feld `name` eines Kursobjekts.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend.
        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: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id`, `category`
          (`title` des zugehörigen Kurskategorieobjekts), `name` und `description`
          eines Kursobjekts gesucht wird.
        schema:
          type: string
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `updated_at` eines Kursobjekts: liefert
          nur Kurse, die zum angegebenen Zeitpunkt oder später geändert wurden (ISO
          8601; der Zeitpunkt selbst zählt mit). Zusammen mit `ordering=updated_at`
          eignet sich das für Delta-Abfragen statt wiederholter Vollabrufe. Auch Änderungen
          an Kursinhalten zählen als Änderung.'
      tags:
      - Kurse
      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: Das ist der allgemeine Kurs im Jahr 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: Allgemeiner Kurs 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:
                  - Thema 1
                  - Thema 2
                  - Thema 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: Das ist der Kurs zum Thema Brandschutz.
                  id: fb86f4d4-bee3-4c70-9a25-8e9dd7fd9aab
                  instructor: 1e5d00d7-1f74-4531-9d9e-37ff9f95522b
                  is_archived: false
                  language_code: de
                  languages:
                    de: true
                  name: Brandschutz Kurs 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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kurse auflisten
      x-required-scope: courses:read
    post:
      operationId: courses_create
      description: |-
        Benötigtes Zugriffsrecht: Kurse – Lesen und Schreiben (`courses:write`).

        Dieser API-Endpunkt erstellt einen Kurs.
      tags:
      - Kurse
      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: Das ist der allgemeine Kurs im Jahr 2026.
                id: 06285ae7-38a0-484a-b779-b11490c706c0
                instructor: af782ace-30a2-4628-837f-fcd807603631
                is_archived: false
                language_code: de
                languages:
                  de: true
                name: Allgemeiner Kurs 2026
                thumbnail: null
                topics:
                - Thema 1
                - Thema 2
                - Thema 3
                updated_at: '2026-01-11T08:25:16'
          description: ''
          headers:
            Idempotent-Replayed:
              schema:
                type: boolean
              description: '`true`, wenn diese Antwort die gespeicherte Antwort einer
                früheren Anfrage mit demselben `Idempotency-Key` ist; fehlt bei der
                Erstausführung.'
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '422':
          description: Der `Idempotency-Key` wurde bereits für eine andere Anfrage
            verwendet.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '409':
          description: Eine Anfrage mit demselben `Idempotency-Key` läuft noch. Wiederholen
            Sie die Anfrage nach der in `Retry-After` angegebenen Zeit.
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Macht die Anfrage sicher wiederholbar: Wird sie mit demselben
          Key erneut gesendet, liefert die API die gespeicherte Antwort der ersten
          erfolgreichen Ausführung, statt erneut auszuführen (24 Stunden lang). Fehlversuche
          verbrauchen den Key nicht. Verwenden Sie für jede neue Operation einen neuen
          Key (z. B. eine UUID), 1 bis 200 Zeichen.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Kurs erstellen
      x-required-scope: courses:write
  /v1/courses/{uuid}/:
    get:
      operationId: courses_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Kurse – Lesen (`courses:read`).

        Dieser API-Endpunkt gibt einen Kurs zurück.
      parameters:
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - category
            - instructor
        description: Felder, die als vollständiges Objekt statt als ID ausgeliefert
          werden.
        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: Sprache der Kursinhalte; fehlt sie im Kurs, gilt die Standardsprache
          des Kurses.
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Kurses.
      tags:
      - Kurse
      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: Das ist der allgemeine Kurs im Jahr 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: Allgemeiner Kurs 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:
                - Thema 1
                - Thema 2
                - Thema 3
                updated_at: '2026-04-14T14:44:42'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kurs abrufen
      x-required-scope: courses:read
    patch:
      operationId: courses_partial_update
      description: |-
        Benötigtes Zugriffsrecht: Kurse – Lesen und Schreiben (`courses:write`).

        Dieser API-Endpunkt bearbeitet einen Kurs.
      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: Sprache, deren Kursübersetzung bearbeitet wird (betrifft die
          Felder `name`, `description` und `topics`); fehlt sie im Kurs, wird die
          Übersetzung der Standardsprache des Kurses bearbeitet.
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Kurses.
      tags:
      - Kurse
      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: Das ist der allgemeine Kurs im Jahr 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: Allgemeiner Kurs 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:
                - Thema 1
                - Thema 2
                - Thema 3
                updated_at: '2026-04-14T14:44:42'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kurs bearbeiten
      x-required-scope: courses:write
    delete:
      operationId: courses_destroy
      description: |-
        Benötigtes Zugriffsrecht: Kurse – Lesen und Schreiben (`courses:write`).

        Dieser API-Endpunkt löscht einen Kurs.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Kurses.
      tags:
      - Kurse
      security:
      - ApiKey: []
      responses:
        '204':
          description: Erfolg, keine Antwortdaten.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kurs löschen
      x-required-scope: courses:write
  /v1/courses/{uuid}/participations/:
    get:
      operationId: courses_participations_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Kursteilnahmen – Lesen (`participations:read`).

        Dieser API-Endpunkt gibt eine Liste aller Kursteilnahmen eines Kurses zurück.
      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: Sprache der Kursinhalte; fehlt sie im Kurs, gilt die Standardsprache
          des Kurses.
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Kurses.
      - in: query
        name: completed_at
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `completed_at` eines Kursteilnahmeobjekts;
          gefiltert wird nach dem Datum (Datumsformat nach ISO 8601: *YYYY-MM-DD*).'
      - in: query
        name: course
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `course` eines Kursteilnahmeobjekts.
      - in: query
        name: due_date
        schema:
          type: string
          format: date
        description: Ein Filter für das Feld `due_date` eines Kursteilnahmeobjekts.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
            - user
        description: Felder, die als vollständiges Objekt statt als ID ausgeliefert
          werden.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Kursteilnahmeobjekts.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend. `user` sortiert nach dem Nachnamen des Benutzers, `course` nach
          dem Kursnamen.
        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: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id`, `user` (`username`,
          `first_name`, `last_name` und `email` des zugehörigen Benutzerobjekts) und
          `course` (`name` des zugehörigen Kursobjekts) eines Kursteilnahmeobjekts
          gesucht wird.
        schema:
          type: string
      - in: query
        name: status
        schema:
          type: string
          enum:
          - done
          - pending
        description: Ein Filter für das Feld `status` eines Kursteilnahmeobjekts.
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `updated_at` eines Kursteilnahmeobjekts:
          liefert nur Kursteilnahmen, die zum angegebenen Zeitpunkt oder später geändert
          wurden (ISO 8601; der Zeitpunkt selbst zählt mit). Zusammen mit `ordering=updated_at`
          eignet sich das für Delta-Abfragen statt wiederholter Vollabrufe.'
      - in: query
        name: user
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `user` eines Kursteilnahmeobjekts.
      tags:
      - Kurse
      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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kursteilnahmen eines Kurses auflisten
      x-required-scope: participations:read
  /v1/courses/{uuid}/ratings/:
    get:
      operationId: courses_ratings_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Kursbewertungen – Lesen (`course-ratings:read`).

        Dieser API-Endpunkt gibt eine Liste aller Bewertungen eines Kurses zurück. Bewertungen sind anonym: Die Liste bleibt leer, bis mindestens fünf Bewertungen für den Kurs abgegeben wurden.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Kurses.
      - in: query
        name: course
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `course` eines Kursbewertungsobjekts.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
        description: Felder, die als vollständiges Objekt statt als ID ausgeliefert
          werden.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Kursbewertungsobjekts.
      - 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: Ein Filter für das Feld `language_code` eines Kursbewertungsobjekts.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend.
        schema:
          type: array
          items:
            type: string
            enum:
            - rating
            - -rating
        style: form
        explode: false
      - name: page
        required: false
        in: query
        description: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          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: Ein Filter für das Feld `rating` eines Kursbewertungsobjekts.
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id`, `course` (`name`
          des zugehörigen Kursobjekts) und `comment` eines Kursbewertungsobjekts gesucht
          wird.
        schema:
          type: string
      tags:
      - Kurse
      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: Der Kurs hat mir gut gefallen.
                  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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Bewertungen eines Kurses auflisten
      x-required-scope: course-ratings:read
  /v1/groups/:
    get:
      operationId: groups_list
      description: |-
        Benötigtes Zugriffsrecht: Gruppen – Lesen (`groups:read`).

        Dieser API-Endpunkt gibt eine Liste aller Gruppen zurück.
      parameters:
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Gruppenobjekts.
      - in: query
        name: name
        schema:
          type: string
        description: Ein Filter für das Feld `name` eines Gruppenobjekts.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend.
        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: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id`, `name` und
          `description` eines Gruppenobjekts gesucht wird.
        schema:
          type: string
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `updated_at` eines Gruppenobjekts: liefert
          nur Gruppen, die zum angegebenen Zeitpunkt oder später geändert wurden (ISO
          8601; der Zeitpunkt selbst zählt mit). Zusammen mit `ordering=updated_at`
          eignet sich das für Delta-Abfragen statt wiederholter Vollabrufe. Auch das
          Hinzufügen und Entfernen von Mitgliedern zählt als Änderung.'
      tags:
      - Gruppen
      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: Diese Gruppe umfasst alle Mitarbeiter.
                  id: 40c40d56-5e5e-438e-9642-184cc44e527a
                  name: Alle Mitarbeiter
                  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: Diese Gruppe umfasst alle Mitarbeiter der Produktion.
                  id: 5679eb14-0268-40dc-890d-18ef5be6f835
                  name: Produktion
                  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: Verwaltung
                  updated_at: '2026-01-11T14:11:37'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Gruppen auflisten
      x-required-scope: groups:read
    post:
      operationId: groups_create
      description: |-
        Benötigtes Zugriffsrecht: Gruppen – Lesen und Schreiben (`groups:write`).

        Dieser API-Endpunkt erstellt eine Gruppe.
      tags:
      - Gruppen
      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: Diese Gruppe umfasst alle Mitarbeiter.
                id: 40c40d56-5e5e-438e-9642-184cc44e527a
                name: Alle Mitarbeiter
                updated_at: '2024-12-06T11:55:22'
          description: ''
          headers:
            Idempotent-Replayed:
              schema:
                type: boolean
              description: '`true`, wenn diese Antwort die gespeicherte Antwort einer
                früheren Anfrage mit demselben `Idempotency-Key` ist; fehlt bei der
                Erstausführung.'
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '422':
          description: Der `Idempotency-Key` wurde bereits für eine andere Anfrage
            verwendet.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '409':
          description: Eine Anfrage mit demselben `Idempotency-Key` läuft noch. Wiederholen
            Sie die Anfrage nach der in `Retry-After` angegebenen Zeit.
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Macht die Anfrage sicher wiederholbar: Wird sie mit demselben
          Key erneut gesendet, liefert die API die gespeicherte Antwort der ersten
          erfolgreichen Ausführung, statt erneut auszuführen (24 Stunden lang). Fehlversuche
          verbrauchen den Key nicht. Verwenden Sie für jede neue Operation einen neuen
          Key (z. B. eine UUID), 1 bis 200 Zeichen.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Gruppe erstellen
      x-required-scope: groups:write
  /v1/groups/{group_uuid}/members/{user_uuid}/:
    get:
      operationId: groups_members_check
      description: |-
        Benötigtes Zugriffsrecht: Gruppen – Lesen (`groups:read`).

        Dieser API-Endpunkt prüft, ob ein Benutzer Mitglied in einer Gruppe ist.
      parameters:
      - in: path
        name: group_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Gruppe.
      - in: path
        name: user_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Benutzers.
      tags:
      - Gruppen
      security:
      - ApiKey: []
      responses:
        '204':
          description: Der Benutzer ist Mitglied der Gruppe.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Der Benutzer ist kein Mitglied der Gruppe.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Gruppenmitgliedschaft prüfen
      x-required-scope: groups:read
    put:
      operationId: groups_members_update
      description: |-
        Benötigtes Zugriffsrecht: Gruppen – Lesen und Schreiben (`groups:write`).

        Dieser API-Endpunkt fügt ein Mitglied zu einer Gruppe hinzu.
      parameters:
      - in: path
        name: group_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Gruppe.
      - in: path
        name: user_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Benutzers.
      tags:
      - Gruppen
      security:
      - ApiKey: []
      responses:
        '204':
          description: Erfolg, keine Antwortdaten.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Mitglied zu einer Gruppe hinzufügen
      x-required-scope: groups:write
    delete:
      operationId: groups_members_destroy
      description: |-
        Benötigtes Zugriffsrecht: Gruppen – Lesen und Schreiben (`groups:write`).

        Dieser API-Endpunkt entfernt ein Mitglied aus einer Gruppe.
      parameters:
      - in: path
        name: group_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Gruppe.
      - in: path
        name: user_uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Benutzers.
      tags:
      - Gruppen
      security:
      - ApiKey: []
      responses:
        '204':
          description: Erfolg, keine Antwortdaten.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Mitglied aus einer Gruppe entfernen
      x-required-scope: groups:write
  /v1/groups/{uuid}/:
    get:
      operationId: groups_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Gruppen – Lesen (`groups:read`).

        Dieser API-Endpunkt gibt eine Gruppe zurück.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Gruppe.
      tags:
      - Gruppen
      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: Diese Gruppe umfasst alle Mitarbeiter.
                id: 40c40d56-5e5e-438e-9642-184cc44e527a
                name: Alle Mitarbeiter
                updated_at: '2024-12-06T11:55:22'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Gruppe abrufen
      x-required-scope: groups:read
    patch:
      operationId: groups_partial_update
      description: |-
        Benötigtes Zugriffsrecht: Gruppen – Lesen und Schreiben (`groups:write`).

        Dieser API-Endpunkt bearbeitet eine Gruppe.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Gruppe.
      tags:
      - Gruppen
      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: Diese Gruppe umfasst alle Mitarbeiter.
                id: 40c40d56-5e5e-438e-9642-184cc44e527a
                name: Alle Mitarbeiter
                updated_at: '2024-12-07T10:29:11'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Gruppe bearbeiten
      x-required-scope: groups:write
    delete:
      operationId: groups_destroy
      description: |-
        Benötigtes Zugriffsrecht: Gruppen – Lesen und Schreiben (`groups:write`).

        Dieser API-Endpunkt löscht eine Gruppe.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Gruppe.
      tags:
      - Gruppen
      security:
      - ApiKey: []
      responses:
        '204':
          description: Erfolg, keine Antwortdaten.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Gruppe löschen
      x-required-scope: groups:write
  /v1/groups/{uuid}/members/:
    get:
      operationId: groups_members_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Benutzer – Lesen (`users:read`).

        Dieser API-Endpunkt gibt eine Liste aller Mitglieder einer Gruppe zurück.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Gruppe.
      - in: query
        name: email
        schema:
          type: string
        description: Ein Filter für das Feld `email` eines Benutzerobjekts.
      - in: query
        name: first_name
        schema:
          type: string
        description: Ein Filter für das Feld `first_name` eines Benutzerobjekts.
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Benutzerobjekts.
      - in: query
        name: is_active
        schema:
          type: boolean
        description: Ein Filter für das Feld `is_active` eines Benutzerobjekts.
      - 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: Ein Filter für das Feld `language` eines Benutzerobjekts.
      - in: query
        name: last_name
        schema:
          type: string
        description: Ein Filter für das Feld `last_name` eines Benutzerobjekts.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend.
        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: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - in: query
        name: requires_password_change
        schema:
          type: boolean
        description: Ein Filter für das Feld `requires_password_change` eines Benutzerobjekts.
      - in: query
        name: role
        schema:
          type: string
          enum:
          - admin
          - billing_manager
          - manager
          - user
        description: Ein Filter für das Feld `role` eines Benutzerobjekts.
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id`, `username`,
          `first_name`, `last_name`, `email` und `description` eines Benutzerobjekts
          gesucht wird.
        schema:
          type: string
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `updated_at` eines Benutzerobjekts:
          liefert nur Benutzer, die zum angegebenen Zeitpunkt oder später geändert
          wurden (ISO 8601; der Zeitpunkt selbst zählt mit). Zusammen mit `ordering=updated_at`
          eignet sich das für Delta-Abfragen statt wiederholter Vollabrufe. Auch das
          Hinzufügen und Entfernen von Gruppenmitgliedschaften zählt als Änderung;
          reine Aktivität (`last_active`) dagegen nicht.'
      - in: query
        name: username
        schema:
          type: string
        description: Ein Filter für das Feld `username` eines Benutzerobjekts.
      tags:
      - Gruppen
      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: Benutzer wurde vorübergehend deaktiviert (Elternzeit).
                  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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Mitglieder einer Gruppe auflisten
      x-required-scope: users:read
  /v1/me/:
    get:
      operationId: me_retrieve
      description: 'Liefert den für den Request verwendeten API-Schlüssel: Name, ID
        und Zugriffsrechte sowie das zugehörige Konto. Funktioniert mit jedem gültigen
        Schlüssel unabhängig von dessen Zugriffsrechten – als Verbindungstest und
        um zu prüfen, welche Rechte ein Schlüssel trägt.'
      tags:
      - API-Schlüssel
      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 des API-Schlüssels, wie im Admin-Bereich
                          vergeben
                      uuid:
                        type: string
                        format: uuid
                        description: Stabile ID des API-Schlüssels
                      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: Zugriffsrechte des Schlüssels, alphabetisch sortiert
                  organization:
                    type: object
                    required:
                    - domain
                    properties:
                      domain:
                        type: string
                        description: Domain des Kontos, zu dem der Schlüssel gehört
              example:
                key:
                  name: Reporting (nur Lesen)
                  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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Aktuellen API-Schlüssel abfragen
  /v1/participations/:
    get:
      operationId: participations_list
      description: |-
        Benötigtes Zugriffsrecht: Kursteilnahmen – Lesen (`participations:read`).

        Dieser API-Endpunkt gibt eine Liste aller Kursteilnahmen zurück.
      parameters:
      - in: query
        name: completed_at
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `completed_at` eines Kursteilnahmeobjekts;
          gefiltert wird nach dem Datum (Datumsformat nach ISO 8601: *YYYY-MM-DD*).'
      - in: query
        name: course
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `course` eines Kursteilnahmeobjekts.
      - in: query
        name: due_date
        schema:
          type: string
          format: date
        description: Ein Filter für das Feld `due_date` eines Kursteilnahmeobjekts.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
            - user
        description: Felder, die als vollständiges Objekt statt als ID ausgeliefert
          werden.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Kursteilnahmeobjekts.
      - 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: Sprache der Kursinhalte; fehlt sie im Kurs, gilt die Standardsprache
          des Kurses.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend. `user` sortiert nach dem Nachnamen des Benutzers, `course` nach
          dem Kursnamen.
        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: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id`, `user` (`username`,
          `first_name`, `last_name` und `email` des zugehörigen Benutzerobjekts) und
          `course` (`name` des zugehörigen Kursobjekts) eines Kursteilnahmeobjekts
          gesucht wird.
        schema:
          type: string
      - in: query
        name: status
        schema:
          type: string
          enum:
          - done
          - pending
        description: Ein Filter für das Feld `status` eines Kursteilnahmeobjekts.
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `updated_at` eines Kursteilnahmeobjekts:
          liefert nur Kursteilnahmen, die zum angegebenen Zeitpunkt oder später geändert
          wurden (ISO 8601; der Zeitpunkt selbst zählt mit). Zusammen mit `ordering=updated_at`
          eignet sich das für Delta-Abfragen statt wiederholter Vollabrufe.'
      - in: query
        name: user
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `user` eines Kursteilnahmeobjekts.
      tags:
      - Kursteilnahmen
      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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kursteilnahmen auflisten
      x-required-scope: participations:read
    post:
      operationId: participations_create
      description: |-
        Benötigtes Zugriffsrecht: Kursteilnahmen – Lesen und Schreiben (`participations:write`).

        Dieser API-Endpunkt erstellt eine Kursteilnahme.
        Auf Wunsch wird der Benutzer per E-Mail über die neue Kursteilnahme informiert, sofort oder zu einem von Ihnen festgelegten Zeitpunkt. Standardmäßig wird keine E-Mail versendet (siehe Body-Parameter `send_email_notification`).
      tags:
      - Kursteilnahmen
      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`, wenn diese Antwort die gespeicherte Antwort einer
                früheren Anfrage mit demselben `Idempotency-Key` ist; fehlt bei der
                Erstausführung.'
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '422':
          description: Der `Idempotency-Key` wurde bereits für eine andere Anfrage
            verwendet.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '409':
          description: Eine Anfrage mit demselben `Idempotency-Key` läuft noch. Wiederholen
            Sie die Anfrage nach der in `Retry-After` angegebenen Zeit.
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Macht die Anfrage sicher wiederholbar: Wird sie mit demselben
          Key erneut gesendet, liefert die API die gespeicherte Antwort der ersten
          erfolgreichen Ausführung, statt erneut auszuführen (24 Stunden lang). Fehlversuche
          verbrauchen den Key nicht. Verwenden Sie für jede neue Operation einen neuen
          Key (z. B. eine UUID), 1 bis 200 Zeichen.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Kursteilnahme erstellen
      x-required-scope: participations:write
  /v1/participations/{uuid}/:
    get:
      operationId: participations_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Kursteilnahmen – Lesen (`participations:read`).

        Dieser API-Endpunkt gibt eine Kursteilnahme zurück.
      parameters:
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
            - user
        description: Felder, die als vollständiges Objekt statt als ID ausgeliefert
          werden.
        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: Sprache der Kursinhalte; fehlt sie im Kurs, gilt die Standardsprache
          des Kurses.
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Kursteilnahme.
      tags:
      - Kursteilnahmen
      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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kursteilnahme abrufen
      x-required-scope: participations:read
    patch:
      operationId: participations_partial_update
      description: |-
        Benötigtes Zugriffsrecht: Kursteilnahmen – Lesen und Schreiben (`participations:write`).

        Dieser API-Endpunkt bearbeitet eine Kursteilnahme.
        Eine E-Mail-Benachrichtigung ist nur beim Erstellen einer Kursteilnahme möglich. Die Body-Parameter `send_email_notification`, `email_scheduled_at` und `email_note` werden hier ignoriert.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Kursteilnahme.
      tags:
      - Kursteilnahmen
      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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kursteilnahme bearbeiten
      x-required-scope: participations:write
    delete:
      operationId: participations_destroy
      description: |-
        Benötigtes Zugriffsrecht: Kursteilnahmen – Lesen und Schreiben (`participations:write`).

        Dieser API-Endpunkt löscht eine Kursteilnahme.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Kursteilnahme.
      tags:
      - Kursteilnahmen
      security:
      - ApiKey: []
      responses:
        '204':
          description: Erfolg, keine Antwortdaten.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kursteilnahme löschen
      x-required-scope: participations:write
  /v1/participations/{uuid}/certificate/:
    get:
      operationId: participations_certificate_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Kursteilnahmen – Lesen (`participations:read`).

        Dieser API-Endpunkt gibt das Teilnahmezertifikat einer Kursteilnahme zurück.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID der Kursteilnahme.
      tags:
      - Kursteilnahmen
      security:
      - ApiKey: []
      responses:
        '200':
          content:
            application/pdf:
              schema:
                type: string
                format: binary
          description: Zertifikat als PDF.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Teilnahmezertifikat abrufen
      x-required-scope: participations:read
  /v1/users/:
    get:
      operationId: users_list
      description: |-
        Benötigtes Zugriffsrecht: Benutzer – Lesen (`users:read`).

        Dieser API-Endpunkt gibt eine Liste aller Benutzer zurück.
      parameters:
      - in: query
        name: email
        schema:
          type: string
        description: Ein Filter für das Feld `email` eines Benutzerobjekts.
      - in: query
        name: first_name
        schema:
          type: string
        description: Ein Filter für das Feld `first_name` eines Benutzerobjekts.
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Benutzerobjekts.
      - in: query
        name: is_active
        schema:
          type: boolean
        description: Ein Filter für das Feld `is_active` eines Benutzerobjekts.
      - 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: Ein Filter für das Feld `language` eines Benutzerobjekts.
      - in: query
        name: last_name
        schema:
          type: string
        description: Ein Filter für das Feld `last_name` eines Benutzerobjekts.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend.
        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: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - in: query
        name: requires_password_change
        schema:
          type: boolean
        description: Ein Filter für das Feld `requires_password_change` eines Benutzerobjekts.
      - in: query
        name: role
        schema:
          type: string
          enum:
          - admin
          - billing_manager
          - manager
          - user
        description: Ein Filter für das Feld `role` eines Benutzerobjekts.
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id`, `username`,
          `first_name`, `last_name`, `email` und `description` eines Benutzerobjekts
          gesucht wird.
        schema:
          type: string
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `updated_at` eines Benutzerobjekts:
          liefert nur Benutzer, die zum angegebenen Zeitpunkt oder später geändert
          wurden (ISO 8601; der Zeitpunkt selbst zählt mit). Zusammen mit `ordering=updated_at`
          eignet sich das für Delta-Abfragen statt wiederholter Vollabrufe. Auch das
          Hinzufügen und Entfernen von Gruppenmitgliedschaften zählt als Änderung;
          reine Aktivität (`last_active`) dagegen nicht.'
      - in: query
        name: username
        schema:
          type: string
        description: Ein Filter für das Feld `username` eines Benutzerobjekts.
      tags:
      - Benutzer
      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: Logistik
                  description: Beschreibung des Benutzers
                  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: Benutzer wurde vorübergehend deaktiviert (Elternzeit).
                  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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Benutzer auflisten
      x-required-scope: users:read
    post:
      operationId: users_create
      description: |-
        Benötigtes Zugriffsrecht: Benutzer – Lesen und Schreiben (`users:write`).

        Dieser API-Endpunkt erstellt einen Benutzer. Wenn Sie den Benutzer mit einem Startpasswort anlegen, setzen Sie `requires_password_change` auf `true`: Der Benutzer muss das Passwort dann beim ersten Login durch ein eigenes ersetzen.
      tags:
      - Benutzer
      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: Logistik
                description: Beschreibung des Benutzers
                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`, wenn diese Antwort die gespeicherte Antwort einer
                früheren Anfrage mit demselben `Idempotency-Key` ist; fehlt bei der
                Erstausführung.'
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '422':
          description: Der `Idempotency-Key` wurde bereits für eine andere Anfrage
            verwendet.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '409':
          description: Eine Anfrage mit demselben `Idempotency-Key` läuft noch. Wiederholen
            Sie die Anfrage nach der in `Retry-After` angegebenen Zeit.
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Macht die Anfrage sicher wiederholbar: Wird sie mit demselben
          Key erneut gesendet, liefert die API die gespeicherte Antwort der ersten
          erfolgreichen Ausführung, statt erneut auszuführen (24 Stunden lang). Fehlversuche
          verbrauchen den Key nicht. Verwenden Sie für jede neue Operation einen neuen
          Key (z. B. eine UUID), 1 bis 200 Zeichen.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Benutzer erstellen
      x-required-scope: users:write
  /v1/users/{uuid}/:
    get:
      operationId: users_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Benutzer – Lesen (`users:read`).

        Dieser API-Endpunkt gibt einen Benutzer zurück.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Benutzers.
      tags:
      - Benutzer
      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: Logistik
                description: Beschreibung des Benutzers
                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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Benutzer abrufen
      x-required-scope: users:read
    patch:
      operationId: users_partial_update
      description: |-
        Benötigtes Zugriffsrecht: Benutzer – Lesen und Schreiben (`users:write`).

        Dieser API-Endpunkt bearbeitet einen Benutzer. Es ändern sich nur die gesendeten Felder. Ein neues `password` allein lässt `requires_password_change` unverändert; senden Sie beide Felder zusammen, um ein Startpasswort zu vergeben und den Wechsel beim nächsten Login zu erzwingen.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Benutzers.
      tags:
      - Benutzer
      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: Logistik
                description: Beschreibung des Benutzers
                email: max.mustermann@example.com
                first_name: Max
                id: 1f53398d-843f-4bc5-8e0f-9841ab294274
                is_active: true
                job_title: Fachkraft für Lagerlogistik
                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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Benutzer bearbeiten
      x-required-scope: users:write
    delete:
      operationId: users_destroy
      description: |-
        Benötigtes Zugriffsrecht: Benutzer – Lesen und Schreiben (`users:write`).

        Dieser API-Endpunkt löscht einen Benutzer.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Benutzers.
      tags:
      - Benutzer
      security:
      - ApiKey: []
      responses:
        '204':
          description: Erfolg, keine Antwortdaten.
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Benutzer löschen
      x-required-scope: users:write
  /v1/users/{uuid}/groups/:
    get:
      operationId: users_groups_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Gruppen – Lesen (`groups:read`).

        Dieser API-Endpunkt gibt eine Liste aller Gruppen eines Benutzers zurück.
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Benutzers.
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Gruppenobjekts.
      - in: query
        name: name
        schema:
          type: string
        description: Ein Filter für das Feld `name` eines Gruppenobjekts.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend.
        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: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id`, `name` und
          `description` eines Gruppenobjekts gesucht wird.
        schema:
          type: string
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `updated_at` eines Gruppenobjekts: liefert
          nur Gruppen, die zum angegebenen Zeitpunkt oder später geändert wurden (ISO
          8601; der Zeitpunkt selbst zählt mit). Zusammen mit `ordering=updated_at`
          eignet sich das für Delta-Abfragen statt wiederholter Vollabrufe. Auch das
          Hinzufügen und Entfernen von Mitgliedern zählt als Änderung.'
      tags:
      - Benutzer
      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: Diese Gruppe umfasst alle Mitarbeiter.
                  id: 40c40d56-5e5e-438e-9642-184cc44e527a
                  name: Alle Mitarbeiter
                  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: Diese Gruppe umfasst alle Mitarbeiter der Produktion.
                  id: 5679eb14-0268-40dc-890d-18ef5be6f835
                  name: Produktion
                  updated_at: '2026-04-17T08:07:52'
          description: ''
          headers:
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Gruppen eines Benutzers auflisten
      x-required-scope: groups:read
  /v1/users/{uuid}/login-link/:
    post:
      operationId: users_login_link_create
      description: "Benötigtes Zugriffsrecht: Login-Links – Erlauben (`login-links:write`).\n\nDieser
        API-Endpunkt erstellt einen Login-Link für einen Benutzer. Login-Links werden
        auch <q>Magic Link</q> genannt.\nMit Login-Links können Benutzer passwortlos
        in Schulungstool eingeloggt werden.\nWird ein Benutzer zum Login-Link weitergeleitet,
        wird der Benutzer über den Login-Link automatisch angemeldet.\nAn den Login-Link
        kann der Parameter `?next=<redirect-url>` angehängt werden. Nach dem Login
        wird der Benutzer automatisch an die `<redirect-url>` (z. B. an die `learn_url`
        einer Kursteilnahme) weitergeleitet. Trägt der Benutzer `requires_password_change:
        true`, legt er nach dem Login zuerst ein neues Passwort fest; die Weiterleitung
        an die `<redirect-url>` folgt danach.\nEinschränkungen:\n- Login-Links können
        nur für Benutzer der Rolle `user` erstellt werden. \n- Login-Links sind nur
        30 Sekunden gültig. Es empfiehlt sich, den Login-Link erst unmittelbar vor
        der Verwendung zu erstellen."
      parameters:
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Benutzers.
      - name: Idempotency-Key
        in: header
        required: false
        description: Wird akzeptiert und validiert, Antworten dieses Endpunkts werden
          aber nie gespeichert oder wiederholt, weil der erzeugte Link nach kurzer
          Zeit abläuft. Jede Anfrage erzeugt einen frischen Link.
        schema:
          type: string
          minLength: 1
          maxLength: 200
      tags:
      - Benutzer
      security:
      - ApiKey: []
      responses:
        '201':
          content:
            application/json:
              schema:
                type: object
                properties:
                  url:
                    type: string
                    format: uri
                    description: Der generierte 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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '422':
          description: Der `Idempotency-Key` wurde bereits für eine andere Anfrage
            verwendet.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Ungültiger `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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Login-Link erstellen
      x-required-scope: login-links:write
  /v1/users/{uuid}/participations/:
    get:
      operationId: users_participations_retrieve
      description: |-
        Benötigtes Zugriffsrecht: Kursteilnahmen – Lesen (`participations:read`).

        Dieser API-Endpunkt gibt eine Liste aller Kursteilnahmen eines Benutzers zurück.
      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: Sprache der Kursinhalte; fehlt sie im Kurs, gilt die Standardsprache
          des Kurses.
      - in: path
        name: uuid
        schema:
          type: string
          format: uuid
        required: true
        description: Die ID des Benutzers.
      - in: query
        name: completed_at
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `completed_at` eines Kursteilnahmeobjekts;
          gefiltert wird nach dem Datum (Datumsformat nach ISO 8601: *YYYY-MM-DD*).'
      - in: query
        name: course
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `course` eines Kursteilnahmeobjekts.
      - in: query
        name: due_date
        schema:
          type: string
          format: date
        description: Ein Filter für das Feld `due_date` eines Kursteilnahmeobjekts.
      - in: query
        name: expand
        schema:
          type: array
          items:
            type: string
            enum:
            - course
            - user
        description: Felder, die als vollständiges Objekt statt als ID ausgeliefert
          werden.
        explode: false
      - in: query
        name: id
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `id` eines Kursteilnahmeobjekts.
      - name: ordering
        in: query
        required: false
        description: Sortierung, mehrere Felder kommagetrennt; `-` davor sortiert
          absteigend. `user` sortiert nach dem Nachnamen des Benutzers, `course` nach
          dem Kursnamen.
        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: Eine Seitenzahl innerhalb der paginierten Ergebnisse.
        schema:
          type: integer
      - name: page_size
        required: false
        in: query
        description: 'Anzahl der Ergebnisse pro Seite, zwischen 1 und 100 (Standard:
          25).'
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 25
      - name: search
        required: false
        in: query
        description: Ein Suchbegriff, nach welchem in den Feldern `id`, `user` (`username`,
          `first_name`, `last_name` und `email` des zugehörigen Benutzerobjekts) und
          `course` (`name` des zugehörigen Kursobjekts) eines Kursteilnahmeobjekts
          gesucht wird.
        schema:
          type: string
      - in: query
        name: status
        schema:
          type: string
          enum:
          - done
          - pending
        description: Ein Filter für das Feld `status` eines Kursteilnahmeobjekts.
      - in: query
        name: updated_after
        schema:
          type: string
          format: date-time
        description: 'Ein Filter für das Feld `updated_at` eines Kursteilnahmeobjekts:
          liefert nur Kursteilnahmen, die zum angegebenen Zeitpunkt oder später geändert
          wurden (ISO 8601; der Zeitpunkt selbst zählt mit). Zusammen mit `ordering=updated_at`
          eignet sich das für Delta-Abfragen statt wiederholter Vollabrufe.'
      - in: query
        name: user
        schema:
          type: string
          format: uuid
        description: Ein Filter für das Feld `user` eines Kursteilnahmeobjekts.
      tags:
      - Benutzer
      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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '404':
          description: Ressource nicht gefunden.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      summary: Kursteilnahmen eines Benutzers auflisten
      x-required-scope: participations:read
  /v1/users/invite/:
    post:
      operationId: users_invite_create
      description: |-
        Benötigtes Zugriffsrecht: Benutzer – Lesen und Schreiben (`users:write`).

        Dieser API-Endpunkt lädt einen Benutzer per E-Mail ein.
      tags:
      - Benutzer
      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`, wenn diese Antwort die gespeicherte Antwort einer
                früheren Anfrage mit demselben `Idempotency-Key` ist; fehlt bei der
                Erstausführung.'
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '401':
          description: API-Schlüssel fehlt oder ist ungültig.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '403':
          description: Dem API-Schlüssel fehlt das Zugriffsrecht, das dieser Endpoint
            verlangt; `error.required_scope` nennt es. Ein Administrator kann es in
            den Entwickleroptionen des Admin-Bereichs vergeben.
          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: Das fehlende Zugriffsrecht (derselbe Wert wie `error.required_scope`
                im Body).
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
        '429':
          description: Durchsatzbegrenzung erreicht (1000 Anfragen pro Minute und
            Konto).
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '400':
          description: Validierungsfehler.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '422':
          description: Der `Idempotency-Key` wurde bereits für eine andere Anfrage
            verwendet.
          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: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
        '409':
          description: Eine Anfrage mit demselben `Idempotency-Key` läuft noch. Wiederholen
            Sie die Anfrage nach der in `Retry-After` angegebenen Zeit.
          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: Wartezeit in Sekunden.
            X-Request-ID:
              schema:
                type: string
              description: Eindeutige ID dieses Requests; Fehler wiederholen sie im
                Fehlerbody. Geben Sie sie bei Support-Anfragen an.
            X-RateLimit-Limit:
              schema:
                type: integer
              description: Maximal erlaubte Anfragen im aktuellen Zeitfenster der
                Durchsatzbegrenzung.
            X-RateLimit-Remaining:
              schema:
                type: integer
              description: Davon nach dieser Anfrage noch verfügbare Anfragen im aktuellen
                Zeitfenster.
            X-RateLimit-Reset:
              schema:
                type: integer
              description: Zeitpunkt, zu dem wieder mindestens eine Anfrage frei wird,
                als Unix-Zeitstempel in Sekunden.
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        description: 'Macht die Anfrage sicher wiederholbar: Wird sie mit demselben
          Key erneut gesendet, liefert die API die gespeicherte Antwort der ersten
          erfolgreichen Ausführung, statt erneut auszuführen (24 Stunden lang). Fehlversuche
          verbrauchen den Key nicht. Verwenden Sie für jede neue Operation einen neuen
          Key (z. B. eine UUID), 1 bis 200 Zeichen.'
        schema:
          type: string
          minLength: 1
          maxLength: 200
      summary: Benutzer einladen
      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 des Kurses
        category:
          type:
          - string
          - 'null'
          format: uuid
          description: ID der Kurskategorie. Dieses Feld ist erweiterbar.
        name:
          type: string
          readOnly: true
          description: Name des Kurses (übersetzt in der Sprache `language_code` des
            Kursobjekts)
        description:
          type: string
          readOnly: true
          description: Beschreibung des Kurses (übersetzt in der Sprache `language_code`
            des Kursobjekts)
        topics:
          type: array
          items:
            type: string
          readOnly: true
          description: Themen des Kurses (übersetzt in der Sprache `language_code`
            des Kursobjekts)
        thumbnail:
          type:
          - object
          - 'null'
          additionalProperties:
            type: object
            properties:
              url:
                type: string
                format: uri
              width:
                type: integer
              height:
                type: integer
          readOnly: true
          description: |-
            Vorschaubild des Kurses in verschiedenen Auflösungen

            *Schlüssel*: Breite des Vorschaubildes

            *Wert*: `Object` mit den *Schlüsseln* `url` (URL des Vorschaubildes), `width` (Breite des Vorschaubildes in Pixeln) und `height` (Höhe des Vorschaubildes in Pixeln).
        instructor:
          type:
          - string
          - 'null'
          format: uuid
          description: ID der Kursleitung. Dieses Feld ist erweiterbar.
        languages:
          type: object
          readOnly: true
          additionalProperties:
            type: boolean
          description: |-
            Übersetzungen des Kurses

            *Schlüssel*: Sprachcode nach ISO 639-1, z. B. `"de"`

            *Wert*: `true` (Übersetzung ist aktiviert) oder `false` (Übersetzung ist deaktiviert)
        language_code:
          type: string
          readOnly: true
          description: Aktuelle Übersetzung des Kursobjekts (Sprachcode nach ISO 639-1,
            z. B. `"de"`)
        default_language_code:
          $ref: '#/components/schemas/LanguageEnum'
          description: Standardsprache des Kurses (Sprachcode nach ISO 639-1, z. B.
            `"de"`)
        is_archived:
          type: boolean
          description: |-
            `true`: Kurs ist archiviert

            `false`: Kurs ist nicht archiviert
        created_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der Erstellung des Kurses
        updated_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der letzten Aktualisierung des Kurses
        dashboard_url:
          type: string
          format: uri
          readOnly: true
          description: URL zur Detailansicht des Kurses im Administrationsbereich
            Ihres Schulungstool-Kontos
      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 der Kurskategorie
        title:
          type: string
          maxLength: 50
          description: Titel der Kurskategorie
        created_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der Erstellung der Kurskategorie
        updated_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der letzten Aktualisierung der Kurskategorie
      required:
      - created_at
      - id
      - title
      - updated_at
    CourseCategoryRequest:
      type: object
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 50
          description: Titel der Kurskategorie
      required:
      - title
    CourseRating:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: ID der Kursbewertung
        course:
          type: string
          format: uuid
          readOnly: true
          description: ID des Kurses der Kursbewertung. Dieses Feld ist erweiterbar.
        language_code:
          allOf:
          - $ref: '#/components/schemas/LanguageEnum'
          readOnly: true
          description: Bewertete Übersetzung des Kurses (Sprachcode nach ISO 639-1,
            z. B. `"de"`)
        rating:
          allOf:
          - $ref: '#/components/schemas/RatingEnum'
          readOnly: true
          description: Bewertung des Kurses von 1 bis 5 Sternen
        comment:
          type: string
          readOnly: true
          description: Kommentar zur Kursbewertung
      required:
      - comment
      - course
      - id
      - language_code
      - rating
    CourseRequest:
      type: object
      properties:
        category:
          type:
          - string
          - 'null'
          format: uuid
          description: ID der Kurskategorie. Dieses Feld ist erweiterbar.
          default: null
        name:
          type: string
          minLength: 1
          maxLength: 250
          description: Name des Kurses (übersetzt in der Sprache `language_code` des
            Kursobjekts)
        description:
          type: string
          description: Beschreibung des Kurses (übersetzt in der Sprache `language_code`
            des Kursobjekts)
          default: ''
        topics:
          type:
          - array
          - 'null'
          items:
            type: string
            minLength: 1
            maxLength: 250
          description: Themen des Kurses (übersetzt in der Sprache `language_code`
            des Kursobjekts)
          default: []
        instructor:
          type: string
          format: uuid
          description: ID der Kursleitung. Dieses Feld ist erweiterbar.
        default_language_code:
          $ref: '#/components/schemas/LanguageEnum'
          description: Standardsprache des Kurses (Sprachcode nach ISO 639-1, z. B.
            `"de"`)
        is_archived:
          type: boolean
          description: |-
            `true`: Kurs ist archiviert

            `false`: Kurs ist nicht archiviert
          default: false
      required:
      - default_language_code
      - instructor
      - name
    Group:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
          description: ID der Gruppe
        name:
          type: string
          maxLength: 255
          description: Name der Gruppe
        description:
          type:
          - string
          - 'null'
          description: Beschreibung der Gruppe
        created_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der Erstellung der Gruppe
        updated_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der letzten Aktualisierung der Gruppe
        dashboard_url:
          type: string
          format: uri
          readOnly: true
          description: URL zur Detailansicht der Gruppe im Administrationsbereich
            Ihres Schulungstool-Kontos
      required:
      - created_at
      - dashboard_url
      - id
      - name
      - updated_at
    GroupRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Name der Gruppe
        description:
          type:
          - string
          - 'null'
          description: Beschreibung der Gruppe
          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: Gesamtzahl der Treffer; eine Seite enthält höchstens `page_size`
            Ergebnisse (standardmäßig 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: Gesamtzahl der Treffer; eine Seite enthält höchstens `page_size`
            Ergebnisse (standardmäßig 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: Gesamtzahl der Treffer; eine Seite enthält höchstens `page_size`
            Ergebnisse (standardmäßig 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: Gesamtzahl der Treffer; eine Seite enthält höchstens `page_size`
            Ergebnisse (standardmäßig 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: Gesamtzahl der Treffer; eine Seite enthält höchstens `page_size`
            Ergebnisse (standardmäßig 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: Gesamtzahl der Treffer; eine Seite enthält höchstens `page_size`
            Ergebnisse (standardmäßig 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 der Kursteilnahme
        user:
          type: string
          format: uuid
          description: ID des Benutzers der Kursteilnahme. Dieses Feld ist erweiterbar.
        course:
          type: string
          format: uuid
          description: ID des Kurses der Kursteilnahme. Dieses Feld ist erweiterbar.
        due_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Fälligkeitsdatum der Kursteilnahme (Datumsformat nach ISO
            8601: *YYYY-MM-DD*, z. B. `"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: Erledigungsdatum der Kursteilnahme
        status:
          allOf:
          - $ref: '#/components/schemas/StatusEnum'
          readOnly: true
          description: |-
            Status der Kursteilnahme

            `done`: Kursteilnahme ist erledigt

            `pending`: Kursteilnahme ist offen
        created_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der Erstellung der Kursteilnahme
        updated_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der letzten Aktualisierung der Kursteilnahme
        learn_url:
          type: string
          format: uri
          readOnly: true
          description: URL zur Kursteilnahme im Benutzerbereich, unter der die Kursteilnahme
            erledigt wird
        dashboard_url:
          type: string
          format: uri
          readOnly: true
          description: URL zur Detailansicht der Kursteilnahme im Administrationsbereich
            Ihres Schulungstool-Kontos
      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 des Benutzers der Kursteilnahme. Dieses Feld ist erweiterbar.
        course:
          type: string
          format: uuid
          description: ID des Kurses der Kursteilnahme. Dieses Feld ist erweiterbar.
        due_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Fälligkeitsdatum der Kursteilnahme (Datumsformat nach ISO
            8601: *YYYY-MM-DD*, z. B. `"2026-12-31"`)'
        send_email_notification:
          type: boolean
          writeOnly: true
          default: false
          description: |-
            `true`: Der Benutzer wird per E-Mail über die neue Kursteilnahme benachrichtigt, so wie beim Zuweisen eines Kurses im Administrationsbereich

            `false`: Es wird keine E-Mail versendet

            Benutzer ohne E-Mail-Adresse und Benutzer mit noch ausstehender Einladung erhalten keine E-Mail; die Kursteilnahme wird trotzdem erstellt. Für deaktivierte Benutzer lässt sich unabhängig von diesem Parameter keine Kursteilnahme erstellen.
        email_scheduled_at:
          type:
          - string
          - 'null'
          format: date-time
          writeOnly: true
          description: Zeitpunkt, zu dem die E-Mail versendet wird. Der Zeitpunkt
            muss in der Zukunft liegen. Ohne Angabe wird die E-Mail sofort versendet.
            Nur zulässig, wenn `send_email_notification` auf `true` gesetzt ist.
        email_note:
          type: string
          writeOnly: true
          maxLength: 2000
          description: Persönliche Nachricht, die in die E-Mail aufgenommen wird (maximal
            2000 Zeichen). Zeilenumbrüche (`\n`) sind erlaubt und werden in der E-Mail
            übernommen. Nur zulässig, wenn `send_email_notification` auf `true` gesetzt
            ist.
      required:
      - course
      - due_date
      - user
    PatchedCourseCategoryRequest:
      type: object
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 50
          description: Titel der Kurskategorie
    PatchedCourseRequest:
      type: object
      properties:
        category:
          type:
          - string
          - 'null'
          format: uuid
          description: ID der Kurskategorie. Dieses Feld ist erweiterbar.
        name:
          type: string
          minLength: 1
          maxLength: 250
          description: Name des Kurses (übersetzt in der Sprache `language_code` des
            Kursobjekts)
        description:
          type: string
          description: Beschreibung des Kurses (übersetzt in der Sprache `language_code`
            des Kursobjekts)
        topics:
          type:
          - array
          - 'null'
          items:
            type: string
            minLength: 1
            maxLength: 250
          description: Themen des Kurses (übersetzt in der Sprache `language_code`
            des Kursobjekts)
        instructor:
          type: string
          format: uuid
          description: ID der Kursleitung. Dieses Feld ist erweiterbar.
        default_language_code:
          $ref: '#/components/schemas/LanguageEnum'
          description: Standardsprache des Kurses (Sprachcode nach ISO 639-1, z. B.
            `"de"`)
        is_archived:
          type: boolean
          description: |-
            `true`: Kurs ist archiviert

            `false`: Kurs ist nicht archiviert
    PatchedGroupRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Name der Gruppe
        description:
          type:
          - string
          - 'null'
          description: Beschreibung der Gruppe
    PatchedParticipationRequest:
      type: object
      properties:
        due_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Fälligkeitsdatum der Kursteilnahme (Datumsformat nach ISO
            8601: *YYYY-MM-DD*, z. B. `"2026-12-31"`)'
    PatchedUserRequest:
      type: object
      properties:
        username:
          type: string
          minLength: 1
          description: Benutzername des Benutzers
          pattern: ^[\w.@+-]+$
          maxLength: 150
        first_name:
          type: string
          maxLength: 150
          description: Vorname des Benutzers
        last_name:
          type: string
          maxLength: 150
          description: Nachname des Benutzers
        password:
          type: string
          writeOnly: true
          minLength: 1
          maxLength: 128
          description: Passwort des Benutzers
        requires_password_change:
          type: boolean
          description: |-
            `true`: Der Benutzer muss ein neues Passwort festlegen, bevor er Schulungstool weiter nutzen kann (beim nächsten Login, bei bestehender Anmeldung sofort)

            `false`: Kein Passwortwechsel erforderlich
        email:
          oneOf:
          - type:
            - string
            - 'null'
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: E-Mail-Adresse des Benutzers für Login und Benachrichtigungen
        notification_email:
          oneOf:
          - type: string
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: Zusätzliche E-Mail-Adresse des Benutzers für Benachrichtigungen
        staff_number:
          type: string
          maxLength: 50
          description: Personalnummer des Benutzers
        description:
          type: string
          description: Beschreibung des Benutzers
        birth_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Geburtsdatum des Benutzers (Datumsformat nach ISO 8601: *YYYY-MM-DD*,
            z. B. `"1990-01-19"`)'
        birth_place:
          type: string
          maxLength: 150
          description: Geburtsort des Benutzers
        organization:
          type: string
          maxLength: 250
          description: Organisation des Benutzers
        department:
          type: string
          maxLength: 150
          description: Abteilung des Benutzers
        job_title:
          type: string
          maxLength: 150
          description: Position des Benutzers
        street_address:
          type: string
          maxLength: 250
          description: Straße und Nr. des Benutzers
        postal_code:
          type: string
          maxLength: 10
          description: Postleitzahl des Benutzers
        city:
          type: string
          maxLength: 150
          description: Ort des Benutzers
        country:
          oneOf:
          - $ref: '#/components/schemas/CountryEnum'
          - $ref: '#/components/schemas/BlankEnum'
          description: Land des Benutzers
        phone:
          type: string
          maxLength: 128
          description: Telefonnummer des Benutzers
        language:
          allOf:
          - $ref: '#/components/schemas/LanguageEnum'
          description: Sprache des Benutzers (Sprachcode nach ISO 639-1, z. B. `"de"`)
        is_active:
          type: boolean
          default: true
          description: |-
            `true`: Benutzer ist aktiviert

            `false`: Benutzer ist deaktiviert
    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 des Benutzers
        username:
          type: string
          description: Benutzername des Benutzers
          pattern: ^[\w.@+-]+$
          maxLength: 150
        first_name:
          type: string
          maxLength: 150
          description: Vorname des Benutzers
        last_name:
          type: string
          maxLength: 150
          description: Nachname des Benutzers
        requires_password_change:
          type: boolean
          description: |-
            `true`: Der Benutzer muss ein neues Passwort festlegen, bevor er Schulungstool weiter nutzen kann (beim nächsten Login, bei bestehender Anmeldung sofort)

            `false`: Kein Passwortwechsel erforderlich
        email:
          oneOf:
          - type:
            - string
            - 'null'
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: E-Mail-Adresse des Benutzers für Login und Benachrichtigungen
        notification_email:
          oneOf:
          - type: string
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: Zusätzliche E-Mail-Adresse des Benutzers für Benachrichtigungen
        staff_number:
          type: string
          maxLength: 50
          description: Personalnummer des Benutzers
        description:
          type: string
          description: Beschreibung des Benutzers
        birth_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Geburtsdatum des Benutzers (Datumsformat nach ISO 8601: *YYYY-MM-DD*,
            z. B. `"1990-01-19"`)'
        birth_place:
          type: string
          maxLength: 150
          description: Geburtsort des Benutzers
        organization:
          type: string
          maxLength: 250
          description: Organisation des Benutzers
        department:
          type: string
          maxLength: 150
          description: Abteilung des Benutzers
        job_title:
          type: string
          maxLength: 150
          description: Position des Benutzers
        street_address:
          type: string
          maxLength: 250
          description: Straße und Nr. des Benutzers
        postal_code:
          type: string
          maxLength: 10
          description: Postleitzahl des Benutzers
        city:
          type: string
          maxLength: 150
          description: Ort des Benutzers
        country:
          oneOf:
          - $ref: '#/components/schemas/CountryEnum'
          - $ref: '#/components/schemas/BlankEnum'
          description: Land des Benutzers
        phone:
          type: string
          maxLength: 128
          description: Telefonnummer des Benutzers
        language:
          allOf:
          - $ref: '#/components/schemas/LanguageEnum'
          description: Sprache des Benutzers (Sprachcode nach ISO 639-1, z. B. `"de"`)
        last_active:
          type:
          - string
          - 'null'
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Letzte Aktivität des Benutzers
        role:
          allOf:
          - $ref: '#/components/schemas/RoleEnum'
          readOnly: true
          description: |-
            Rolle des Benutzers

            `user`: Benutzer

            `manager`: Manager

            `billing_manager`: Abrechnungsmanager

            `admin`: Administrator
        is_active:
          type: boolean
          default: true
          description: |-
            `true`: Benutzer ist aktiviert

            `false`: Benutzer ist deaktiviert
        deactivated_at:
          type:
          - string
          - 'null'
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der Deaktivierung; `null`, solange der Benutzer aktiv
            ist.
        created_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der Erstellung des Benutzers
        updated_at:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
          readOnly: true
          description: Zeitpunkt der letzten Aktualisierung des Benutzers
        dashboard_url:
          type: string
          format: uri
          readOnly: true
          description: URL zur Detailansicht des Benutzers im Administrationsbereich
            Ihres Schulungstool-Kontos
      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: E-Mail-Adresse des Benutzers, der eingeladen wird
        inviter:
          type: string
          format: uuid
          description: ID des Benutzers, der den neuen Benutzer einlädt
        language:
          allOf:
          - $ref: '#/components/schemas/LanguageEnum'
          description: Sprache der E-Mail-Einladung (Sprachcode nach ISO 639-1, z.
            B. `"de"`)
          default: de
      required:
      - email
      - inviter
    UserRequest:
      type: object
      properties:
        username:
          type: string
          minLength: 1
          description: Benutzername des Benutzers
          pattern: ^[\w.@+-]+$
          maxLength: 150
        first_name:
          type: string
          maxLength: 150
          description: Vorname des Benutzers
        last_name:
          type: string
          maxLength: 150
          description: Nachname des Benutzers
        password:
          type: string
          writeOnly: true
          minLength: 1
          maxLength: 128
          description: Passwort des Benutzers
        requires_password_change:
          type: boolean
          description: |-
            `true`: Der Benutzer muss ein neues Passwort festlegen, bevor er Schulungstool weiter nutzen kann (beim nächsten Login, bei bestehender Anmeldung sofort)

            `false`: Kein Passwortwechsel erforderlich
          default: false
        email:
          oneOf:
          - type:
            - string
            - 'null'
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: E-Mail-Adresse des Benutzers für Login und Benachrichtigungen
          default: null
        notification_email:
          oneOf:
          - type: string
            format: email
            maxLength: 254
          - type: string
            maxLength: 0
          description: Zusätzliche E-Mail-Adresse des Benutzers für Benachrichtigungen
          default: ''
        staff_number:
          type: string
          maxLength: 50
          description: Personalnummer des Benutzers
          default: ''
        description:
          type: string
          description: Beschreibung des Benutzers
          default: ''
        birth_date:
          type:
          - string
          - 'null'
          format: date
          description: 'Geburtsdatum des Benutzers (Datumsformat nach ISO 8601: *YYYY-MM-DD*,
            z. B. `"1990-01-19"`)'
          default: null
        birth_place:
          type: string
          maxLength: 150
          description: Geburtsort des Benutzers
          default: ''
        organization:
          type: string
          maxLength: 250
          description: Organisation des Benutzers
          default: ''
        department:
          type: string
          maxLength: 150
          description: Abteilung des Benutzers
          default: ''
        job_title:
          type: string
          maxLength: 150
          description: Position des Benutzers
          default: ''
        street_address:
          type: string
          maxLength: 250
          description: Straße und Nr. des Benutzers
          default: ''
        postal_code:
          type: string
          maxLength: 10
          description: Postleitzahl des Benutzers
          default: ''
        city:
          type: string
          maxLength: 150
          description: Ort des Benutzers
          default: ''
        country:
          oneOf:
          - $ref: '#/components/schemas/CountryEnum'
          - $ref: '#/components/schemas/BlankEnum'
          description: Land des Benutzers
          default: ''
        phone:
          type: string
          maxLength: 128
          description: Telefonnummer des Benutzers
          default: ''
        language:
          allOf:
          - $ref: '#/components/schemas/LanguageEnum'
          description: Sprache des Benutzers (Sprachcode nach ISO 639-1, z. B. `"de"`)
          default: de
        is_active:
          type: boolean
          default: true
          description: |-
            `true`: Benutzer ist aktiviert

            `false`: Benutzer ist deaktiviert
      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: Eindeutige ID dieses Requests. Geben Sie sie bei Support-Anfragen
                an, damit wir den Request in unseren Logs finden.
            required_scope:
              type: string
              description: Nur bei `MissingScope`-Fehlern enthalten.
            doc_url:
              type: string
              description: Nur bei `MissingScope`-Fehlern enthalten.
            field_errors:
              type: object
              additionalProperties:
                type: array
                items:
                  type: string
              description: Nur bei `ValidationError`.
            non_field_errors:
              type: array
              items:
                type: string
              description: Nur bei `ValidationError`.
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      description: |-
        API-Schlüssel aus *Einstellungen > Erweiterte Einstellungen > Entwickleroptionen*. Header `Authorization: Token <API-Schlüssel>`; `Bearer <API-Schlüssel>` wird ebenfalls akzeptiert.

        Jeder Schlüssel trägt Zugriffsrechte (Scopes), die bestimmen, welche Endpoints er aufrufen darf; jede Operation nennt unten ihr benötigtes Zugriffsrecht. Ohne das benötigte Recht antwortet die API mit `403` und `error.type: "MissingScope"` samt dem fehlenden Scope in `error.required_scope`. `GET /v1/me/` liefert die Zugriffsrechte des verwendeten Schlüssels. Details: [Zugriffsrechte-Guide](https://docs.api.schulungstool.de/guides/authentication/#access-scopes).

        | Ressource | Scopes |
        |---|---|
        | Benutzer | `users:read`, `users:write` |
        | Gruppen | `groups:read`, `groups:write` |
        | Kurse | `courses:read`, `courses:write` |
        | Kurskategorien | `course-categories:read`, `course-categories:write` |
        | Kursbewertungen | `course-ratings:read` |
        | Kursteilnahmen | `participations:read`, `participations:write` |
        | Login-Links | `login-links:write` |
servers:
- url: https://api.schulungstool.de
  description: Produktion
x-tagGroups:
- name: Allgemeines
  tags:
  - API-Schlüssel
- name: Kursverwaltung
  tags:
  - Kurse
  - Kurskategorien
  - Kursbewertungen
  - Kursteilnahmen
- name: Benutzerverwaltung
  tags:
  - Benutzer
  - Gruppen
- name: Webhooks
  tags:
  - Webhooks
webhooks:
  participation.created:
    post:
      operationId: webhook_participation_created
      summary: Kursteilnahme erstellt
      description: 'Wird gesendet, wenn eine Kursteilnahme erstellt wird: durch Administratoren,
        durch wiederkehrende Schulungen, per Import oder über die API. Den aktuellen
        Stand liefert `GET /v1/participations/{id}/`.'
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: Die Event-ID, bei allen Zustellversuchen identisch (gleicher
          Wert wie `id` im Body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix-Zeitstempel (Sekunden) dieses Zustellversuchs; Teil des
          signierten Inhalts.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signatur dieser Zustellung nach der [Standard-Webhooks](https://www.standardwebhooks.com/)-Spezifikation:
          `v1,<Base64>`. Während einer Secret-Rotation enthält der Header mehrere
          Signaturen, durch Leerzeichen getrennt; eine gültige Signatur genügt.'
      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: 'Eindeutige Event-ID (`msg_...`). Bei allen Zustellversuchen
                    dieses Events identisch: Nutzen Sie sie, um Events idempotent
                    zu verarbeiten.'
                type:
                  type: string
                  const: participation.created
                  description: Der Event-Typ. Empfänger müssen unbekannte Typen ignorieren,
                    damit neue Typen Ihre Integration nicht brechen.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'Zeitpunkt des Events: RFC 3339 in UTC mit genau sechs
                    Nachkommastellen und `Z`-Suffix, dadurch lexikografisch sortierbar.'
                api_version:
                  type: string
                  const: v1
                  description: Version des Datenvertrags (aktuell `v1`).
                tenant:
                  type: string
                  description: Domain des Workspace, zu dem das Event gehört, z. B.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stabile ID des Workspace. Hilfreich, wenn ein Empfänger
                    mehrere Workspaces bedient.
                data:
                  type: object
                  required:
                  - id
                  - user
                  - course
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'ID der Kursteilnahme: `GET /v1/participations/{id}/`.'
                    user:
                      type: string
                      format: uuid
                      description: 'ID des zugewiesenen Benutzers: `GET /v1/users/{id}/`.'
                    course:
                      type: string
                      format: uuid
                      description: 'ID des Kurses: `GET /v1/courses/{id}/`.'
                  description: 'Die Event-Daten: nur IDs. Den aktuellen Objektzustand
                    laden Sie über die API nach; Empfänger müssen unbekannte Felder
                    ignorieren.'
            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: Jeder 2xx-Status bestätigt die Zustellung. Jede andere Antwort,
            auch Redirects, zählt als Fehlschlag und die Zustellung wird mit exponentiellem
            Backoff wiederholt.
  participation.completed:
    post:
      operationId: webhook_participation_completed
      summary: Kursteilnahme erledigt
      description: Wird bei jedem Abschluss einer Kursteilnahme gesendet, unabhängig
        davon, wer sie abgeschlossen hat (Lernende, Administratoren oder API). Den
        aktuellen Stand liefert `GET /v1/participations/{id}/`.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: Die Event-ID, bei allen Zustellversuchen identisch (gleicher
          Wert wie `id` im Body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix-Zeitstempel (Sekunden) dieses Zustellversuchs; Teil des
          signierten Inhalts.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signatur dieser Zustellung nach der [Standard-Webhooks](https://www.standardwebhooks.com/)-Spezifikation:
          `v1,<Base64>`. Während einer Secret-Rotation enthält der Header mehrere
          Signaturen, durch Leerzeichen getrennt; eine gültige Signatur genügt.'
      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: 'Eindeutige Event-ID (`msg_...`). Bei allen Zustellversuchen
                    dieses Events identisch: Nutzen Sie sie, um Events idempotent
                    zu verarbeiten.'
                type:
                  type: string
                  const: participation.completed
                  description: Der Event-Typ. Empfänger müssen unbekannte Typen ignorieren,
                    damit neue Typen Ihre Integration nicht brechen.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'Zeitpunkt des Events: RFC 3339 in UTC mit genau sechs
                    Nachkommastellen und `Z`-Suffix, dadurch lexikografisch sortierbar.'
                api_version:
                  type: string
                  const: v1
                  description: Version des Datenvertrags (aktuell `v1`).
                tenant:
                  type: string
                  description: Domain des Workspace, zu dem das Event gehört, z. B.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stabile ID des Workspace. Hilfreich, wenn ein Empfänger
                    mehrere Workspaces bedient.
                data:
                  type: object
                  required:
                  - id
                  - user
                  - course
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'ID der Kursteilnahme: `GET /v1/participations/{id}/`.'
                    user:
                      type: string
                      format: uuid
                      description: 'ID des zugewiesenen Benutzers: `GET /v1/users/{id}/`.'
                    course:
                      type: string
                      format: uuid
                      description: 'ID des Kurses: `GET /v1/courses/{id}/`.'
                  description: 'Die Event-Daten: nur IDs. Den aktuellen Objektzustand
                    laden Sie über die API nach; Empfänger müssen unbekannte Felder
                    ignorieren.'
            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: Jeder 2xx-Status bestätigt die Zustellung. Jede andere Antwort,
            auch Redirects, zählt als Fehlschlag und die Zustellung wird mit exponentiellem
            Backoff wiederholt.
  participation.certificate_created:
    post:
      operationId: webhook_participation_certificate_created
      summary: Zertifikat erstellt
      description: Wird gesendet, wenn das Zertifikat zu einer erledigten Kursteilnahme
        erzeugt wurde. Herunterladen per `GET /v1/participations/{id}/certificate/`.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: Die Event-ID, bei allen Zustellversuchen identisch (gleicher
          Wert wie `id` im Body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix-Zeitstempel (Sekunden) dieses Zustellversuchs; Teil des
          signierten Inhalts.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signatur dieser Zustellung nach der [Standard-Webhooks](https://www.standardwebhooks.com/)-Spezifikation:
          `v1,<Base64>`. Während einer Secret-Rotation enthält der Header mehrere
          Signaturen, durch Leerzeichen getrennt; eine gültige Signatur genügt.'
      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: 'Eindeutige Event-ID (`msg_...`). Bei allen Zustellversuchen
                    dieses Events identisch: Nutzen Sie sie, um Events idempotent
                    zu verarbeiten.'
                type:
                  type: string
                  const: participation.certificate_created
                  description: Der Event-Typ. Empfänger müssen unbekannte Typen ignorieren,
                    damit neue Typen Ihre Integration nicht brechen.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'Zeitpunkt des Events: RFC 3339 in UTC mit genau sechs
                    Nachkommastellen und `Z`-Suffix, dadurch lexikografisch sortierbar.'
                api_version:
                  type: string
                  const: v1
                  description: Version des Datenvertrags (aktuell `v1`).
                tenant:
                  type: string
                  description: Domain des Workspace, zu dem das Event gehört, z. B.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stabile ID des Workspace. Hilfreich, wenn ein Empfänger
                    mehrere Workspaces bedient.
                data:
                  type: object
                  required:
                  - id
                  - user
                  - course
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'ID der Kursteilnahme: `GET /v1/participations/{id}/`.'
                    user:
                      type: string
                      format: uuid
                      description: 'ID des zugewiesenen Benutzers: `GET /v1/users/{id}/`.'
                    course:
                      type: string
                      format: uuid
                      description: 'ID des Kurses: `GET /v1/courses/{id}/`.'
                  description: 'Die Event-Daten: nur IDs. Den aktuellen Objektzustand
                    laden Sie über die API nach; Empfänger müssen unbekannte Felder
                    ignorieren.'
            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: Jeder 2xx-Status bestätigt die Zustellung. Jede andere Antwort,
            auch Redirects, zählt als Fehlschlag und die Zustellung wird mit exponentiellem
            Backoff wiederholt.
  participation.deleted:
    post:
      operationId: webhook_participation_deleted
      summary: Kursteilnahme gelöscht
      description: Wird gesendet, wenn eine Kursteilnahme in den Papierkorb verschoben
        wird, auch wenn sie mit ihrem Benutzer entfernt wurde. `data` enthält nur
        die ID und den Löschzeitpunkt; das Objekt ist nicht mehr abrufbar.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: Die Event-ID, bei allen Zustellversuchen identisch (gleicher
          Wert wie `id` im Body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix-Zeitstempel (Sekunden) dieses Zustellversuchs; Teil des
          signierten Inhalts.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signatur dieser Zustellung nach der [Standard-Webhooks](https://www.standardwebhooks.com/)-Spezifikation:
          `v1,<Base64>`. Während einer Secret-Rotation enthält der Header mehrere
          Signaturen, durch Leerzeichen getrennt; eine gültige Signatur genügt.'
      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: 'Eindeutige Event-ID (`msg_...`). Bei allen Zustellversuchen
                    dieses Events identisch: Nutzen Sie sie, um Events idempotent
                    zu verarbeiten.'
                type:
                  type: string
                  const: participation.deleted
                  description: Der Event-Typ. Empfänger müssen unbekannte Typen ignorieren,
                    damit neue Typen Ihre Integration nicht brechen.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'Zeitpunkt des Events: RFC 3339 in UTC mit genau sechs
                    Nachkommastellen und `Z`-Suffix, dadurch lexikografisch sortierbar.'
                api_version:
                  type: string
                  const: v1
                  description: Version des Datenvertrags (aktuell `v1`).
                tenant:
                  type: string
                  description: Domain des Workspace, zu dem das Event gehört, z. B.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stabile ID des Workspace. Hilfreich, wenn ein Empfänger
                    mehrere Workspaces bedient.
                data:
                  type: object
                  required:
                  - id
                  - deleted_at
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: ID des gelöschten Objekts.
                    deleted_at:
                      type: string
                      pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
                      description: 'Löschzeitpunkt im v1-Zeitformat: lokale Zeit,
                        sekundengenau, ohne Offset.'
                  description: 'Die Event-Daten: nur IDs. Den aktuellen Objektzustand
                    laden Sie über die API nach; Empfänger müssen unbekannte Felder
                    ignorieren.'
            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: Jeder 2xx-Status bestätigt die Zustellung. Jede andere Antwort,
            auch Redirects, zählt als Fehlschlag und die Zustellung wird mit exponentiellem
            Backoff wiederholt.
  user.created:
    post:
      operationId: webhook_user_created
      summary: Benutzer erstellt
      description: 'Wird gesendet, wenn ein Benutzerkonto erstellt wird: durch Administratoren,
        per Import, per Selbstregistrierung oder über die API. Den aktuellen Stand
        liefert `GET /v1/users/{id}/`.'
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: Die Event-ID, bei allen Zustellversuchen identisch (gleicher
          Wert wie `id` im Body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix-Zeitstempel (Sekunden) dieses Zustellversuchs; Teil des
          signierten Inhalts.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signatur dieser Zustellung nach der [Standard-Webhooks](https://www.standardwebhooks.com/)-Spezifikation:
          `v1,<Base64>`. Während einer Secret-Rotation enthält der Header mehrere
          Signaturen, durch Leerzeichen getrennt; eine gültige Signatur genügt.'
      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: 'Eindeutige Event-ID (`msg_...`). Bei allen Zustellversuchen
                    dieses Events identisch: Nutzen Sie sie, um Events idempotent
                    zu verarbeiten.'
                type:
                  type: string
                  const: user.created
                  description: Der Event-Typ. Empfänger müssen unbekannte Typen ignorieren,
                    damit neue Typen Ihre Integration nicht brechen.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'Zeitpunkt des Events: RFC 3339 in UTC mit genau sechs
                    Nachkommastellen und `Z`-Suffix, dadurch lexikografisch sortierbar.'
                api_version:
                  type: string
                  const: v1
                  description: Version des Datenvertrags (aktuell `v1`).
                tenant:
                  type: string
                  description: Domain des Workspace, zu dem das Event gehört, z. B.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stabile ID des Workspace. Hilfreich, wenn ein Empfänger
                    mehrere Workspaces bedient.
                data:
                  type: object
                  required:
                  - id
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'ID des Benutzers: `GET /v1/users/{id}/`.'
                  description: 'Die Event-Daten: nur IDs. Den aktuellen Objektzustand
                    laden Sie über die API nach; Empfänger müssen unbekannte Felder
                    ignorieren.'
            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: Jeder 2xx-Status bestätigt die Zustellung. Jede andere Antwort,
            auch Redirects, zählt als Fehlschlag und die Zustellung wird mit exponentiellem
            Backoff wiederholt.
  user.activated:
    post:
      operationId: webhook_user_activated
      summary: Benutzer aktiviert
      description: Wird gesendet, wenn ein deaktiviertes Benutzerkonto wieder aktiviert
        wird. Den aktuellen Stand liefert `GET /v1/users/{id}/`.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: Die Event-ID, bei allen Zustellversuchen identisch (gleicher
          Wert wie `id` im Body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix-Zeitstempel (Sekunden) dieses Zustellversuchs; Teil des
          signierten Inhalts.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signatur dieser Zustellung nach der [Standard-Webhooks](https://www.standardwebhooks.com/)-Spezifikation:
          `v1,<Base64>`. Während einer Secret-Rotation enthält der Header mehrere
          Signaturen, durch Leerzeichen getrennt; eine gültige Signatur genügt.'
      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: 'Eindeutige Event-ID (`msg_...`). Bei allen Zustellversuchen
                    dieses Events identisch: Nutzen Sie sie, um Events idempotent
                    zu verarbeiten.'
                type:
                  type: string
                  const: user.activated
                  description: Der Event-Typ. Empfänger müssen unbekannte Typen ignorieren,
                    damit neue Typen Ihre Integration nicht brechen.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'Zeitpunkt des Events: RFC 3339 in UTC mit genau sechs
                    Nachkommastellen und `Z`-Suffix, dadurch lexikografisch sortierbar.'
                api_version:
                  type: string
                  const: v1
                  description: Version des Datenvertrags (aktuell `v1`).
                tenant:
                  type: string
                  description: Domain des Workspace, zu dem das Event gehört, z. B.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stabile ID des Workspace. Hilfreich, wenn ein Empfänger
                    mehrere Workspaces bedient.
                data:
                  type: object
                  required:
                  - id
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'ID des Benutzers: `GET /v1/users/{id}/`.'
                  description: 'Die Event-Daten: nur IDs. Den aktuellen Objektzustand
                    laden Sie über die API nach; Empfänger müssen unbekannte Felder
                    ignorieren.'
            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: Jeder 2xx-Status bestätigt die Zustellung. Jede andere Antwort,
            auch Redirects, zählt als Fehlschlag und die Zustellung wird mit exponentiellem
            Backoff wiederholt.
  user.deactivated:
    post:
      operationId: webhook_user_deactivated
      summary: Benutzer deaktiviert
      description: Wird gesendet, wenn ein Benutzerkonto deaktiviert wird. Den aktuellen
        Stand liefert `GET /v1/users/{id}/`.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: Die Event-ID, bei allen Zustellversuchen identisch (gleicher
          Wert wie `id` im Body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix-Zeitstempel (Sekunden) dieses Zustellversuchs; Teil des
          signierten Inhalts.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signatur dieser Zustellung nach der [Standard-Webhooks](https://www.standardwebhooks.com/)-Spezifikation:
          `v1,<Base64>`. Während einer Secret-Rotation enthält der Header mehrere
          Signaturen, durch Leerzeichen getrennt; eine gültige Signatur genügt.'
      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: 'Eindeutige Event-ID (`msg_...`). Bei allen Zustellversuchen
                    dieses Events identisch: Nutzen Sie sie, um Events idempotent
                    zu verarbeiten.'
                type:
                  type: string
                  const: user.deactivated
                  description: Der Event-Typ. Empfänger müssen unbekannte Typen ignorieren,
                    damit neue Typen Ihre Integration nicht brechen.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'Zeitpunkt des Events: RFC 3339 in UTC mit genau sechs
                    Nachkommastellen und `Z`-Suffix, dadurch lexikografisch sortierbar.'
                api_version:
                  type: string
                  const: v1
                  description: Version des Datenvertrags (aktuell `v1`).
                tenant:
                  type: string
                  description: Domain des Workspace, zu dem das Event gehört, z. B.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stabile ID des Workspace. Hilfreich, wenn ein Empfänger
                    mehrere Workspaces bedient.
                data:
                  type: object
                  required:
                  - id
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: 'ID des Benutzers: `GET /v1/users/{id}/`.'
                  description: 'Die Event-Daten: nur IDs. Den aktuellen Objektzustand
                    laden Sie über die API nach; Empfänger müssen unbekannte Felder
                    ignorieren.'
            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: Jeder 2xx-Status bestätigt die Zustellung. Jede andere Antwort,
            auch Redirects, zählt als Fehlschlag und die Zustellung wird mit exponentiellem
            Backoff wiederholt.
  user.deleted:
    post:
      operationId: webhook_user_deleted
      summary: Benutzer gelöscht
      description: Wird gesendet, wenn ein Benutzerkonto in den Papierkorb verschoben
        wird. Für dabei entfernte Kursteilnahmen kommen eigene `participation.deleted`-Events.
        `data` enthält nur die ID und den Löschzeitpunkt.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: Die Event-ID, bei allen Zustellversuchen identisch (gleicher
          Wert wie `id` im Body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix-Zeitstempel (Sekunden) dieses Zustellversuchs; Teil des
          signierten Inhalts.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signatur dieser Zustellung nach der [Standard-Webhooks](https://www.standardwebhooks.com/)-Spezifikation:
          `v1,<Base64>`. Während einer Secret-Rotation enthält der Header mehrere
          Signaturen, durch Leerzeichen getrennt; eine gültige Signatur genügt.'
      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: 'Eindeutige Event-ID (`msg_...`). Bei allen Zustellversuchen
                    dieses Events identisch: Nutzen Sie sie, um Events idempotent
                    zu verarbeiten.'
                type:
                  type: string
                  const: user.deleted
                  description: Der Event-Typ. Empfänger müssen unbekannte Typen ignorieren,
                    damit neue Typen Ihre Integration nicht brechen.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'Zeitpunkt des Events: RFC 3339 in UTC mit genau sechs
                    Nachkommastellen und `Z`-Suffix, dadurch lexikografisch sortierbar.'
                api_version:
                  type: string
                  const: v1
                  description: Version des Datenvertrags (aktuell `v1`).
                tenant:
                  type: string
                  description: Domain des Workspace, zu dem das Event gehört, z. B.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stabile ID des Workspace. Hilfreich, wenn ein Empfänger
                    mehrere Workspaces bedient.
                data:
                  type: object
                  required:
                  - id
                  - deleted_at
                  properties:
                    id:
                      type: string
                      format: uuid
                      description: ID des gelöschten Objekts.
                    deleted_at:
                      type: string
                      pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$
                      description: 'Löschzeitpunkt im v1-Zeitformat: lokale Zeit,
                        sekundengenau, ohne Offset.'
                  description: 'Die Event-Daten: nur IDs. Den aktuellen Objektzustand
                    laden Sie über die API nach; Empfänger müssen unbekannte Felder
                    ignorieren.'
            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: Jeder 2xx-Status bestätigt die Zustellung. Jede andere Antwort,
            auch Redirects, zählt als Fehlschlag und die Zustellung wird mit exponentiellem
            Backoff wiederholt.
  ping:
    post:
      operationId: webhook_ping
      summary: Testevent (ping)
      description: Wird nur über *Testevent senden* in den Entwickleroptionen gesendet.
        `data` ist immer leer. Testevents der übrigen Typen verwenden die Beispielwerte
        aus dieser Referenz.
      tags:
      - Webhooks
      security: []
      parameters:
      - name: webhook-id
        in: header
        required: true
        schema:
          type: string
        example: msg_7f3c0a1b2c3d4e5f60718293a4b5c6d7
        description: Die Event-ID, bei allen Zustellversuchen identisch (gleicher
          Wert wie `id` im Body).
      - name: webhook-timestamp
        in: header
        required: true
        schema:
          type: integer
        example: 1792245600
        description: Unix-Zeitstempel (Sekunden) dieses Zustellversuchs; Teil des
          signierten Inhalts.
      - name: webhook-signature
        in: header
        required: true
        schema:
          type: string
        example: v1,K5oZfzN95Z9UVu1EsPQudpsQmdzsAr2cIGfOXE9zfKY=
        description: 'Signatur dieser Zustellung nach der [Standard-Webhooks](https://www.standardwebhooks.com/)-Spezifikation:
          `v1,<Base64>`. Während einer Secret-Rotation enthält der Header mehrere
          Signaturen, durch Leerzeichen getrennt; eine gültige Signatur genügt.'
      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: 'Eindeutige Event-ID (`msg_...`). Bei allen Zustellversuchen
                    dieses Events identisch: Nutzen Sie sie, um Events idempotent
                    zu verarbeiten.'
                type:
                  type: string
                  const: ping
                  description: Der Event-Typ. Empfänger müssen unbekannte Typen ignorieren,
                    damit neue Typen Ihre Integration nicht brechen.
                occurred_at:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$
                  description: 'Zeitpunkt des Events: RFC 3339 in UTC mit genau sechs
                    Nachkommastellen und `Z`-Suffix, dadurch lexikografisch sortierbar.'
                api_version:
                  type: string
                  const: v1
                  description: Version des Datenvertrags (aktuell `v1`).
                tenant:
                  type: string
                  description: Domain des Workspace, zu dem das Event gehört, z. B.
                    `ihre-firma.schulungstool.de`.
                tenant_id:
                  type: string
                  format: uuid
                  description: Stabile ID des Workspace. Hilfreich, wenn ein Empfänger
                    mehrere Workspaces bedient.
                data:
                  type: object
                  description: Immer leer.
                  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: Jeder 2xx-Status bestätigt die Zustellung. Jede andere Antwort,
            auch Redirects, zählt als Fehlschlag und die Zustellung wird mit exponentiellem
            Backoff wiederholt.
tags:
- name: Kurskategorien
  description: Kategorien zur Gliederung des Kurskatalogs.
- name: Kursbewertungen
  description: Bewertungen der Teilnehmenden zu Kursen.
- name: Kurse
  description: Kurse abrufen und aktualisieren.
- name: Gruppen
  description: Benutzergruppen und ihre Mitglieder.
- name: API-Schlüssel
  description: Der für den Request verwendete API-Schlüssel samt Zugriffsrechten.
- name: Kursteilnahmen
  description: Zuweisungen von Benutzern zu Kursen samt Status und Zertifikat.
- name: Benutzer
  description: Benutzerkonten verwalten, einladen und deaktivieren.
- name: Webhooks
  description: Webhooks liefern Events zu Benutzern und Kursteilnahmen als signierte
    POST-Requests an Ihren HTTPS-Endpunkt. Administratoren richten Endpunkte in der
    Verwaltung unter *Einstellungen → Erweiterte Einstellungen → Entwickleroptionen
    → Webhooks* ein. Wie Sie Events empfangen und verifizieren, erklärt der [Webhooks-Guide](https://docs.api.schulungstool.de/de/guides/webhooks/).
