> ## 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.

# Publier le brouillon

> Valide le brouillon, crée un job de compilation et retourne immédiatement
`202 Accepted`. La compilation ne s'exécute **jamais** dans la requête HTTP :
un corpus important demande plusieurs lots LLM, bien au-delà de la limite de
la passerelle.

Le brouillon ne devient la configuration active qu'à la fin de la
compilation. Une ancienne version compilée reste lisible pour terminer les
sessions qui l'utilisent déjà.

Un second publish du même domaine alors qu'un job est `queued` ou `running`
retourne `409 compilation_in_progress` avec le `compilation_id` en cours.

Suivre l'avancement avec
`GET /v1/configuration/compilations/{compilation_id}`.




## OpenAPI

````yaml /openapi.fr.yaml post /v1/configuration/publish
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/publish:
    post:
      tags:
        - configuration
      summary: Publier le brouillon
      description: >
        Valide le brouillon, crée un job de compilation et retourne
        immédiatement

        `202 Accepted`. La compilation ne s'exécute **jamais** dans la requête
        HTTP :

        un corpus important demande plusieurs lots LLM, bien au-delà de la
        limite de

        la passerelle.


        Le brouillon ne devient la configuration active qu'à la fin de la

        compilation. Une ancienne version compilée reste lisible pour terminer
        les

        sessions qui l'utilisent déjà.


        Un second publish du même domaine alors qu'un job est `queued` ou
        `running`

        retourne `409 compilation_in_progress` avec le `compilation_id` en
        cours.


        Suivre l'avancement avec

        `GET /v1/configuration/compilations/{compilation_id}`.
      operationId: publishConfiguration
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublishRequest'
            examples:
              publication_simple:
                summary: Publier la révision courante du brouillon
                value: {}
              publication_verrouillee:
                summary: >-
                  Refuser de publier si le brouillon a bougé depuis la dernière
                  lecture
                value:
                  expected_draft_revision: 42
      responses:
        '202':
          description: Job de compilation créé.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompilationStatus'
              example:
                request_id: req_82bd
                compilation_id: cmp_01K2QF
                status: queued
                draft_revision: 42
                created_at: '2026-09-01T09:20:11Z'
                updated_at: '2026-09-01T09:20:11Z'
                progress: 0
                error: null
                configuration_version: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/InsufficientScope'
        '409':
          $ref: '#/components/responses/PublishConflict'
        '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:
    PublishRequest:
      type: object
      additionalProperties: false
      properties:
        expected_draft_revision:
          type: integer
          minimum: 0
          description: >
            Refuse la publication si le brouillon a changé depuis cette
            révision.

            Recommandé depuis Studio pour éviter de publier le travail d'un
            autre

            éditeur.
    CompilationStatus:
      type: object
      additionalProperties: false
      required:
        - request_id
        - compilation_id
        - status
        - draft_revision
        - created_at
        - updated_at
        - progress
        - error
        - configuration_version
      properties:
        request_id:
          type: string
        compilation_id:
          type: string
          minLength: 1
          maxLength: 128
        status:
          type: string
          enum:
            - queued
            - running
            - succeeded
            - failed
        draft_revision:
          type: integer
          minimum: 0
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        progress:
          type: number
          minimum: 0
          maximum: 1
          description: Avancement indicatif, sans garantie de linéarité.
        error:
          oneOf:
            - $ref: '#/components/schemas/CompilationError'
            - type: 'null'
        configuration_version:
          type:
            - string
            - 'null'
          description: Version désormais active, renseignée uniquement en `succeeded`.
    CompilationError:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      description: >
        Cause bornée d'un échec de compilation. Aucune trace interne, aucun
        prompt et

        aucun contenu de lot n'est exposé.


        `details` n'est renseigné que pour `validation_failed`, dont les erreurs
        sont

        corrigeables par l'éditeur ; pour `llm_unavailable`, `timeout` et

        `internal_error`, il reste absent.
      properties:
        code:
          type: string
          enum:
            - validation_failed
            - llm_unavailable
            - timeout
            - internal_error
        message:
          type: string
          minLength: 1
        details:
          type: array
          items:
            $ref: '#/components/schemas/ConfigurationIssue'
    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
    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.
    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
  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
    PublishConflict:
      description: >-
        Une compilation est déjà en cours, ou la clé d'idempotence a été
        réutilisée.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            compilation_in_progress:
              summary: Un job est déjà queued ou running pour ce domaine
              value:
                code: compilation_in_progress
                message: Une compilation est déjà en cours pour cette configuration.
                request_id: req_9005
                details:
                  compilation_id: cmp_01K2QF
                  status: running
            idempotency_key_reused:
              summary: Même clé, corps différent
              value:
                code: idempotency_key_reused
                message: Cette clé d'idempotence est déjà associée à une autre requête.
                request_id: req_9006
                details:
                  idempotency_key: publish-rev-42
    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.