> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zelinqa.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Appliquer des changements au brouillon

> Applique **atomiquement** une liste ordonnée d'opérations au brouillon :
soit toutes réussissent, soit aucune n'est écrite. Les identifiants fournis
par l'appelant sont conservés ; ils restent stables entre les publications.

Cette route ne publie rien. Le brouillon devient actif uniquement après
`POST /v1/configuration/publish` et la fin de la compilation.

Les erreurs de validation sont renvoyées groupées dans
`configuration_validation_failed`, avec la position de chaque opération
fautive, afin que Studio puisse toutes les afficher d'un coup.




## OpenAPI

````yaml /openapi.fr.yaml post /v1/configuration/changes
openapi: 3.1.0
info:
  title: Zelinqa — API V1
  version: 1.0.0
  summary: >-
    Contrat public du runtime Zelinqa et de la configuration des bases de
    questions.
  description: >-
    Contrat public de l'API Zelinqa V1 sur https://api.zelinqa.ai. La clé API
    identifie le domaine et ses droits. Les mutations utilisent Idempotency-Key
    ; celles d'une session existante utilisent aussi state_version. Les sessions
    restent attachées à leur version publiée.
  contact:
    name: Zelinqa
    url: https://docs.zelinqa.ai
  license:
    name: Proprietary — Zelinqa SAS
    identifier: LicenseRef-Zelinqa-Proprietary
servers:
  - url: https://api.zelinqa.ai
    description: API publique Zelinqa
security:
  - ApiKeyAuth: []
tags:
  - name: sessions
    description: >
      Cycle de vie d'une conversation Zelinqa : création, sélection de la
      question

      suivante, mises à jour hors tour, reprise et retour de résultat.
  - name: configuration
    description: |
      Lecture et modification de la configuration éditoriale d'un domaine, puis
      publication asynchrone de l'artefact moteur.
paths:
  /v1/configuration/changes:
    post:
      tags:
        - configuration
      summary: Appliquer des changements au brouillon
      description: >
        Applique **atomiquement** une liste ordonnée d'opérations au brouillon :

        soit toutes réussissent, soit aucune n'est écrite. Les identifiants
        fournis

        par l'appelant sont conservés ; ils restent stables entre les
        publications.


        Cette route ne publie rien. Le brouillon devient actif uniquement après

        `POST /v1/configuration/publish` et la fin de la compilation.


        Les erreurs de validation sont renvoyées groupées dans

        `configuration_validation_failed`, avec la position de chaque opération

        fautive, afin que Studio puisse toutes les afficher d'un coup.
      operationId: applyConfigurationChanges
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConfigurationChangesRequest'
            examples:
              ajout_question_et_information:
                summary: >-
                  Ajouter une question puis l'information de réussite qu'elle
                  collecte
                value:
                  changes:
                    - entity: question
                      operation: create
                      question:
                        id: q_delivery_window
                        text: À quelle période souhaitez-vous être livré ?
                        type: single_choice
                        dimension_id: so_livraison
                        active: true
                        choices:
                          - id: choice_1m
                            label: Dans le mois
                          - id: choice_3m
                            label: Dans les trois mois
                          - id: choice_later
                            label: Plus tard
                    - entity: success_information
                      operation: create
                      success_information:
                        id: delivery_window
                        label: Fenêtre de livraison souhaitée
                        primary_question_id: q_delivery_window
                        schema:
                          type: string
                          enum:
                            - dans_le_mois
                            - trois_mois
                            - plus_tard
              desactivation:
                summary: Retirer une question du corpus actif sans la supprimer
                value:
                  changes:
                    - entity: question
                      operation: update
                      question:
                        id: q_style
                        active: false
              reglage_objectif:
                summary: Passer le niveau de qualification en approfondi
                value:
                  changes:
                    - entity: objective
                      operation: update
                      objective:
                        qualification_level: deep
                        max_turns: 12
      responses:
        '200':
          description: Brouillon mis à jour.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConfigurationChangesResponse'
              example:
                request_id: req_71aa
                draft_revision: 42
                applied: 2
                warnings: []
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/InsufficientScope'
        '409':
          $ref: '#/components/responses/IdempotencyConflict'
        '422':
          $ref: '#/components/responses/ConfigurationValidationFailed'
        '503':
          $ref: '#/components/responses/IdempotencyContention'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      schema:
        type: string
        minLength: 8
        maxLength: 128
      description: >
        Clé unique par mutation logique, choisie par l'appelant.


        Même clé et même corps renvoient exactement la réponse d'origine, sans

        rejouer l'effet : aucun retry ne double `turn_count`, un outcome, un

        événement, un feedback ou une publication. Même clé avec un corps
        différent

        produit `409 idempotency_key_reused`.


        Les enregistrements sont isolés par tenant et par opération, et sont
        purgés

        après **24 heures**. Passé ce délai, la même clé est traitée comme
        neuve.
  schemas:
    ConfigurationChangesRequest:
      type: object
      additionalProperties: false
      required:
        - changes
      properties:
        expected_draft_revision:
          type: integer
          minimum: 0
          description: >
            Si fourni, les changements ne sont appliqués que si le brouillon est

            toujours à cette révision. Sinon `configuration_validation_failed`
            avec

            le code `draft_revision_mismatch`.
        changes:
          type: array
          minItems: 1
          maxItems: 500
          items:
            $ref: '#/components/schemas/ConfigurationChange'
          description: Opérations appliquées dans l'ordre, atomiquement.
    ConfigurationChangesResponse:
      type: object
      additionalProperties: false
      required:
        - request_id
        - draft_revision
        - applied
        - warnings
      properties:
        request_id:
          type: string
        draft_revision:
          type: integer
          minimum: 0
          description: Nouvelle révision du brouillon après application.
        applied:
          type: integer
          minimum: 0
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/ConfigurationIssue'
          description: |
            Anomalies non bloquantes pour l'édition, mais qui empêcheront la
            publication si elles ne sont pas corrigées.
    ConfigurationChange:
      oneOf:
        - $ref: '#/components/schemas/ObjectiveChange'
        - $ref: '#/components/schemas/DimensionChange'
        - $ref: '#/components/schemas/SuccessInformationChange'
        - $ref: '#/components/schemas/QuestionChange'
      discriminator:
        propertyName: entity
        mapping:
          objective: '#/components/schemas/ObjectiveChange'
          dimension: '#/components/schemas/DimensionChange'
          success_information: '#/components/schemas/SuccessInformationChange'
          question: '#/components/schemas/QuestionChange'
    ConfigurationIssue:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      description: >-
        Anomalie de configuration, structurée pour être affichée telle quelle
        dans Studio.
      properties:
        code:
          type: string
          minLength: 1
          maxLength: 100
          description: >-
            Code d'anomalie stable, en minuscules avec des traits de
            soulignement. Traitez les codes connus et affichez le message
            associé pour tout autre code ; le catalogue peut évoluer avec les
            règles de validation.
        message:
          type: string
          minLength: 1
        entity:
          type: string
          enum:
            - objective
            - dimension
            - success_information
            - question
        entity_id:
          type: string
          maxLength: 128
        change_index:
          type: integer
          minimum: 0
          description: >-
            Position de l'opération fautive dans `changes`, lorsque l'anomalie
            vient d'un changement.
    ErrorEnvelope:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - request_id
        - details
      description: Enveloppe uniforme de toutes les erreurs métier.
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
          minLength: 1
        request_id:
          type: string
          minLength: 1
        details:
          type: object
          additionalProperties: true
    ObjectiveChange:
      type: object
      additionalProperties: false
      required:
        - entity
        - operation
        - objective
      properties:
        entity:
          type: string
          const: objective
        operation:
          type: string
          const: update
          description: L'objectif existe toujours ; il ne peut être ni créé ni supprimé.
        objective:
          type: object
          additionalProperties: false
          minProperties: 1
          properties:
            name:
              type: string
              minLength: 1
              maxLength: 200
            description:
              type: string
              maxLength: 4000
            qualification_level:
              $ref: '#/components/schemas/QualificationLevel'
            max_turns:
              type: integer
              minimum: 1
              maximum: 100
            candidates_per_call:
              type: integer
              minimum: 1
              maximum: 10
            order_strength:
              type: number
              minimum: 0
              maximum: 1
    DimensionChange:
      type: object
      additionalProperties: false
      required:
        - entity
        - operation
        - dimension
      properties:
        entity:
          type: string
          const: dimension
        operation:
          type: string
          enum:
            - create
            - update
            - delete
        dimension:
          type: object
          additionalProperties: false
          required:
            - id
          properties:
            id:
              type: string
              minLength: 1
              maxLength: 128
            name:
              type: string
              minLength: 1
              maxLength: 200
            order_position:
              type: integer
              minimum: 0
            completion_role:
              $ref: '#/components/schemas/CompletionRole'
    SuccessInformationChange:
      type: object
      additionalProperties: false
      required:
        - entity
        - operation
        - success_information
      properties:
        entity:
          type: string
          const: success_information
        operation:
          type: string
          enum:
            - create
            - update
            - delete
        success_information:
          type: object
          additionalProperties: false
          required:
            - id
          properties:
            id:
              type: string
              minLength: 1
              maxLength: 128
            label:
              type: string
              minLength: 1
              maxLength: 200
            schema:
              type: object
              additionalProperties: true
            primary_question_id:
              type: string
              minLength: 1
              maxLength: 128
    QuestionChange:
      type: object
      additionalProperties: false
      required:
        - entity
        - operation
        - question
      properties:
        entity:
          type: string
          const: question
        operation:
          type: string
          enum:
            - create
            - update
            - delete
        question:
          type: object
          additionalProperties: false
          required:
            - id
          properties:
            id:
              type: string
              minLength: 1
              maxLength: 128
            text:
              type: string
              minLength: 1
              maxLength: 4000
            type:
              $ref: '#/components/schemas/QuestionType'
            selection_mode:
              type:
                - string
                - 'null'
              enum:
                - single
                - multiple
                - null
            source:
              $ref: '#/components/schemas/QuestionSource'
            choices:
              type: array
              maxItems: 50
              items:
                $ref: '#/components/schemas/ConfiguredChoice'
            dimension_id:
              type: string
              minLength: 1
              maxLength: 128
            active:
              type: boolean
    ErrorCode:
      type: string
      description: Catalogue fermé des erreurs métier V1.
      enum:
        - unauthorized
        - insufficient_scope
        - idempotency_contention
        - state_version_conflict
        - idempotency_key_reused
        - unknown_session
        - invalid_previous_turn
        - constraint_no_match
        - invalid_choice
        - compiled_artifact_unavailable
        - configuration_validation_failed
        - compilation_in_progress
        - unknown_configuration
        - unknown_compilation
    QualificationLevel:
      type: string
      enum:
        - essential
        - balanced
        - deep
      description: >-
        Une dimension est couverte après 1 intention distincte en essential, 2
        en balanced ou 3 en deep, dans la limite des intentions disponibles. Des
        questions proches peuvent partager une intention. Un conflit de données
        non résolu garde la dimension bloquée. La réussite globale exige aussi
        des informations de réussite conclues et une couverture moyenne des
        dimensions contributives de 0.00, 0.80 ou 1.00 respectivement, sauf
        décision explicite du client. Ce n'est pas un pourcentage de questions
        posées.
    CompletionRole:
      type: string
      enum:
        - blocking
        - contributing
        - optional
      description: >-
        Rôle dans la qualification globale : les données des dimensions blocking
        doivent être conclues ; une dimension blocking sans donnée ne bloque pas
        seule la réussite. Les dimensions contributing participent au seuil
        moyen du niveau. Les dimensions optional n'imposent pas de seuil de
        couverture, mais les informations de réussite configurées restent
        exigées, sauf exclusion ou décision explicite du client.
    QuestionType:
      type: string
      enum:
        - open
        - single_choice
        - multiple_choice
        - semi_open
      description: |
        - `open` : réponse libre, aucun choix ;
        - `single_choice` : un seul choix parmi la liste ;
        - `multiple_choice` : plusieurs choix possibles ;
        - `semi_open` : choix proposés, complément libre autorisé via
          `structured_answer.free_text`.

        Pour `semi_open`, `selection_mode` précise si un ou plusieurs choix sont
        permis en plus du complément libre.
    QuestionSource:
      type: string
      enum:
        - user
        - llm_generated
      description: Provenance éditoriale de la question.
    ConfiguredChoice:
      type: object
      additionalProperties: false
      required:
        - id
        - label
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 128
        label:
          type: string
          minLength: 1
          maxLength: 500
        maps_to_value:
          description: |
            Valeur produite pour l'information de réussite lorsque ce choix est
            sélectionné. Permet le mapping déterministe sans appel LLM.
  responses:
    Unauthorized:
      description: >-
        Réponse 401 possible au niveau de l'application. Une clé absente ou
        invalide est généralement refusée en 403 par la passerelle, sans
        enveloppe métier garantie.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            code: unauthorized
            message: Clé d'intégration absente ou invalide.
            request_id: req_9000
            details: {}
    InsufficientScope:
      description: >-
        Accès refusé. La passerelle peut renvoyer 403 pour une clé absente,
        invalide, expirée, révoquée ou dépourvue du scope requis, sans enveloppe
        métier garantie.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            code: insufficient_scope
            message: Cette clé ne permet pas de publier une configuration.
            request_id: req_9001
            details:
              required_scopes:
                - configuration:publish
              granted_scopes:
                - configuration:read
                - configuration:write
    IdempotencyConflict:
      description: La clé d'idempotence a déjà servi pour un corps différent.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            code: idempotency_key_reused
            message: Cette clé d'idempotence est déjà associée à une autre requête.
            request_id: req_9002
            details:
              idempotency_key: create-session-8842
    ConfigurationValidationFailed:
      description: |
        La validation du brouillon a échoué. Toutes les anomalies sont renvoyées
        ensemble, avec la position de l'opération fautive lorsqu'elle vient d'un
        changement, afin que Studio puisse les afficher d'un seul coup.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            validation_publication:
              summary: Le brouillon n'est pas publiable
              value:
                code: configuration_validation_failed
                message: La configuration comporte 2 anomalies bloquantes.
                request_id: req_9015
                details:
                  issues:
                    - code: success_information_without_active_question
                      message: >-
                        L'information « Fenêtre de livraison souhaitée » n'a pas
                        de question active.
                      entity: success_information
                      entity_id: delivery_window
                    - code: success_information_only_in_optional_dimension
                      message: >-
                        L'information « Budget annuel » ne dépend que d'une
                        dimension optionnel.
                      entity: success_information
                      entity_id: annual_budget
            revision_perimee:
              summary: Le brouillon a changé depuis la lecture du client
              value:
                code: configuration_validation_failed
                message: Le brouillon a été modifié depuis votre dernière lecture.
                request_id: req_9016
                details:
                  issues:
                    - code: draft_revision_mismatch
                      message: Révision attendue 42, révision courante 44.
                      entity: objective
    IdempotencyContention:
      description: >
        La clé d'idempotence n'a pas pu être réservée après deux tentatives, à
        cause

        d'un cycle anormal de requêtes concurrentes portant la même clé.


        Ce n'est **pas** une erreur du client et ce n'est pas un conflit :
        réessayer

        après un court délai a des chances d'aboutir. À distinguer de

        `idempotency_key_reused`, qui est définitif pour ce couple clé/corps.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            code: idempotency_contention
            message: La clé d'idempotence n'a pas pu être réservée, réessayez.
            request_id: req_9017
            details:
              idempotency_key: next-ses01J8Z-turn-4
              retry_after_seconds: 1
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: Zelinqa API key
      description: >-
        Envoyez la clé API dans Authorization: Bearer <clé>. Elle identifie le
        domaine et les droits autorisés. Ne transmettez pas d'en-têtes
        d'identité internes.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.