Spécification du Format de Sondage Ouvert

Publié 15 novembre 2025 · Mis à jour 15 septembre 2026

Un format ouvert, basé sur JSON, pour définir des sondages et des formulaires. Utilisé par YourOpinion.is et libre d’implémentation pour tous.

Version actuelle : 1.0

Version Markdown Simplifiée

Alternativement, il existe un protocole d’importation simplifié basé sur Markdown, conçu principalement pour les agents d’IA. Ce protocole utilise un dialecte « Rich Markdown » pour définir les questions, les options et les sauts de page à l’aide d’un formatage de texte standard. Au lieu de construire un objet JSON profondément imbriqué, un agent génère une chaîne Markdown structurée et l’encode dans une URL unique cliquable. Un clic sur le lien reconstruit instantanément le sondage dans le navigateur.

Télécharger la Spécification

  • Schéma JSON - Définition du format lisible par machine
  • Markdown - Documentation lisible par l’humain (optimisée pour les LLM)

Introduction

Le Format de Sondage Ouvert fournit une méthode standardisée pour définir des sondages, des questionnaires et des formulaires en tant qu’objets JSON. Ce format permet :

  • Portabilité - Déplacer des sondages entre différentes plateformes et outils
  • Contrôle de version - Suivre les modifications du sondage avec des outils de comparaison (diff) standards
  • Génération programmatique - Créer des sondages dynamiquement à partir de code
  • Compatibilité LLM - Les assistants IA peuvent facilement créer et modifier des sondages

Concepts Fondamentaux

Collections (Pages)

Les sondages sont organisés en collections, qui fonctionnent comme des pages ou des sections. Chaque sondage doit contenir au moins une collection.

Éléments

Composants individuels au sein d’une collection, tels que :

  • Questions (saisie de texte, choix multiples, évaluations, etc.)
  • Blocs de contenu (texte Markdown, images)
  • Éléments de contrôle de flux (logique conditionnelle, sauts de page)

Ressources

Composants réutilisables pouvant être référencés par plusieurs questions :

  • Listes d’options (pour les questions à sélection)
  • Échelles d’évaluation
  • Ressources partagées

Structure du Document

Un sondage est représenté comme un objet JSON avec la structure suivante :

{
    "$schema": "https://youropinion.is/json-schema/1.0",
    "$readme": "https://youropinion.is/docs/survey-format.md",
    "collections": {
        "collection-id-1": {
            "name": "Nom de la Collection",
            "elements": {
                "element-id-1": {
                    "type": "Markdown",
                    "data": {
                        /* Données spécifiques à l'élément */
                    }
                }
            },
            "displayOrder": ["element-id-1"]
        }
    },
    "displayOrder": ["collection-id-1"],
    "assets": {
        "asset-id-1": {
            "type": "options",
            "data": {
                /* Données spécifiques à la ressource */
            }
        }
    }
}

Propriétés de Premier Niveau

$schema (optionnel)

URL vers la définition du Schéma JSON pour la validation :

"$schema": "https://youropinion.is/json-schema/1.0"

$readme (optionnel)

URL vers la documentation lisible par l’humain :

"$readme": "https://youropinion.is/docs/survey-format.md"

collections (obligatoire)

Objet contenant les pages/sections du sondage. Chaque clé est un ID de collection unique :

"collections": {
    "welcome": {
        "name": "Page d'accueil",
        "elements": { /* ... */ },
        "displayOrder": ["intro", "consent"]
    },
    "questions": {
        "name": "Questions principales",
        "elements": { /* ... */ },
        "displayOrder": ["q1", "q2", "q3"]
    }
}

Propriétés de la Collection :

  • name (chaîne, optionnel) - Nom lisible par l’humain pour la collection (non affiché aux utilisateurs, utilisé pour référence)
  • condition (objet, optionnel) - Logique conditionnelle pour déterminer si cette collection doit être affichée (voir la section Logique Conditionnelle)
  • elements (objet) - Contient les éléments de cette collection. Chaque clé est un ID d’élément unique
  • displayOrder (tableau) - Tableau d’ID d’éléments définissant l’ordre d’affichage

Important : Le tableau displayOrder agit à la fois comme un filtre et un séquenceur :

  • Seuls les éléments listés dans displayOrder seront affichés.
  • Les éléments non présents dans displayOrder restent dans la définition mais sont masqués.
  • Inclure un ID d’élément inexistant provoquera une erreur.

displayOrder (obligatoire)

Tableau spécifiant l’ordre des collections :

"displayOrder": ["welcome", "questions", "thank-you"]

Les mêmes règles de filtrage s’appliquent : seules les collections listées ici seront affichées.

assets (optionnel)

Composants réutilisables référencés par plusieurs éléments. Les ressources réduisent la duplication et facilitent la maintenance des sondages.

Types de ressources :

  1. options - Listes d’options réutilisables pour les questions SelectOne/SelectMany
  2. ordinal-scale - Échelles étiquetées réutilisables pour les questions OrdinalScale
  3. interval-scale - Échelles numériques réutilisables pour les questions IntervalScale
  4. condition - Une condition nommée (un segment) pour les conditions de collection et les éléments FlowControl

Exemple - Ressource d’options :

"assets": {
    "color-options": {
        "type": "options",
        "name": "Options de couleur",
        "data": {
            "options": {
                "red": { "label": "Rouge" },
                "blue": { "label": "Bleu" },
                "green": { "label": "Vert" },
                "yellow": { "label": "Jaune" }
            },
            "displayOrder": ["red", "blue", "green", "yellow"]
        }
    },
    "satisfaction-scale": {
        "type": "ordinal-scale",
        "name": "Échelle de satisfaction standard",
        "data": {
            "labels": {
                "1": "Très insatisfait",
                "2": "Insatisfait",
                "3": "Neutre",
                "4": "Satisfait",
                "5": "Très satisfait"
            }
        }
    },
    "nps-scale": {
        "type": "interval-scale",
        "name": "Échelle Net Promoter Score (NPS)",
        "data": {
            "start": 0,
            "end": 10,
            "labels": {
                "start": "Peu probable",
                "end": "Très probable"
            }
        }
    },
    "detractors": {
        "type": "condition",
        "name": "Détracteurs",
        "data": {
            "type": "condition",
            "fact": "questions/nps-score",
            "operator": "lte",
            "compare": { "value": 6 }
        }
    }
}

Tous les types de ressources nécessitent :

  • type - Type de ressource : "options", "ordinal-scale", "interval-scale", ou "condition"
  • name - Nom lisible par l’humain à des fins de documentation
  • data - Structure de données spécifique au type

Les ressources peuvent être référencées en utilisant des références JSON (voir la section Références JSON).


Types d’Éléments

Les éléments sont les blocs de construction de votre sondage. Chaque élément a une propriété type et data. Tous les éléments peuvent optionnellement inclure un objet extensions pour des métadonnées personnalisées (non utilisé par le moteur de rendu standard).

Types d’éléments disponibles :

Type Catégorie Description
Markdown Contenu Afficher du texte et du contenu formatés
FlowControl Contrôle Logique conditionnelle et navigation
String Question Saisie de texte (une ou plusieurs lignes)
OpenList Question Liste d’entrées textuelles ajoutées par l’utilisateur
Number Question Saisie numérique
Date Question Sélecteur de date
Boolean Question Case à cocher Oui/Non
SelectOne Question Choix unique parmi des options (boutons radio)
SelectMany Question Choix multiples parmi des options (cases à cocher)
Ranking Question Classer plusieurs options par importance ou préférence
IntervalScale Question Échelle d’évaluation numérique (ex. : 0-10 pour le NPS, 1-5 pour la satisfaction)
OrdinalScale Question Échelle d’évaluation étiquetée (ex. : de « Fortement en désaccord » à « Fortement d’accord »)
Payment Question Élément de traitement de paiement

Éléments de Contenu

Markdown

Affiche du texte formaté, des titres, des listes et d’autres contenus en utilisant la syntaxe Markdown.

{
    "type": "Markdown",
    "data": {
        "markdown": "# Bienvenue !\n\nMerci de participer à notre sondage.\n\n- Veuillez répondre honnêtement\n- Toutes les réponses sont anonymes"
    }
}

Markdown pris en charge :

  • Titres (#, ##, ###)
  • Listes (ordonnées et non ordonnées)
  • Gras (**texte**) et italique (*texte*)
  • Liens ([texte](url))
  • Blocs de code

FlowControl

Contrôle le flux du sondage avec une logique conditionnelle et de la navigation.

{
    "type": "FlowControl",
    "data": {
        "condition": {
            /* Optionnel - Voir la section Logique Conditionnelle */
        },
        "action": {
            "type": "survey-finish" // Options : "survey-finish" ou "page-finish"
        }
    }
}

Types d’Action :

  • survey-finish - Termine le sondage immédiatement
  • page-finish - Termine la page actuelle et passe à la suivante

Pour des informations détaillées sur la structure des conditions et des exemples, voir la section Logique Conditionnelle ci-dessous.


Types de Questions

Toutes les questions partagent ces propriétés communes :

{
    "type": "QuestionType",
    "data": {
        "label": "Le texte de votre question ici",
        "required": "yes", // Optionnel : "yes", "no", ou "suggested" (par défaut : "no")
        "markdown": "Texte d'aide" // Optionnel : contexte additionnel en Markdown
    }
}

Propriétés communes :

  • label (chaîne, obligatoire) - Le texte de la question affiché aux utilisateurs
  • required (chaîne, optionnel) - Indique si une réponse est requise : "yes", "no", ou "suggested" (affiché comme optionnel mais encouragé)
  • markdown (chaîne, optionnel) - Texte d’aide ou description supplémentaire au format Markdown
  • defaultValue (tout type, optionnel) - Valeur pré-remplie pour la question
  • variants (objet, optionnel, à côté de data) - La question modifiée pour un segment, voir Variantes

String

Saisie de texte sur une ou plusieurs lignes.

{
    "type": "String",
    "data": {
        "label": "Quel est votre nom ?",
        "placeholder": "Entrez votre nom complet", // Optionnel
        "multiline": false, // Optionnel : true pour une zone de texte
        "required": "yes"
    }
}

OpenList

Entrées de texte multiples sous forme de liste. Les utilisateurs peuvent ajouter des éléments un par un.

{
    "type": "OpenList",
    "data": {
        "label": "Listez vos principales priorités",
        "multiline": false, // Optionnel : true pour les entrées de paragraphe
        "minItems": 1, // Optionnel : nombre minimum d'éléments
        "maxItems": 5, // Optionnel : nombre maximum d'éléments
        "required": "yes"
    }
}

Propriétés :

  • multiline (booléen, optionnel) - Si true, chaque élément est un paragraphe (zone de texte). Si false (par défaut), chaque élément est une seule ligne
  • minItems (nombre, optionnel) - Nombre minimum d’éléments requis
  • maxItems (nombre, optionnel) - Nombre maximum d’éléments autorisés

Number

Saisie numérique avec validation optionnelle.

{
    "type": "Number",
    "data": {
        "label": "Combien d'employés ?",
        "min": 1, // Optionnel : valeur minimale
        "max": 1000, // Optionnel : valeur maximale
        "step": 1, // Optionnel : taille de l'incrément (par défaut : 1)
        "required": "yes"
    }
}

Propriétés :

  • min (nombre, optionnel) - Valeur minimale autorisée
  • max (nombre, optionnel) - Valeur maximale autorisée
  • step (nombre, optionnel) - Taille de l’incrément pour la validation de la saisie (par défaut : 1)

Date

Sélecteur de date avec niveau de précision et contraintes min/max optionnels.

{
    "type": "Date",
    "data": {
        "label": "Quand nous avez-vous rejoints ?",
        "required": "suggested",
        "accuracy": "day", // Optionnel : "day", "month", ou "year" (par défaut : "day")
        "min": "2020-01-01", // Optionnel : date la plus ancienne sélectionnable
        "max": "2025-12-31" // Optionnel : date la plus récente sélectionnable
    }
}

Propriétés :

  • accuracy (chaîne, optionnel) - Niveau de précision de la date :
    • "day" - Sélecteur de date complet avec calendrier (par défaut)
    • "month" - Sélection du mois et de l’année via des menus déroulants
    • "year" - Sélection de l’année uniquement via un menu déroulant
  • min (chaîne, optionnel) - Date la plus ancienne sélectionnable. Peut être :
    • Une chaîne de date ISO (ex. : "2020-01-01")
    • Une chaîne de temps relatif (ex. : "+ 3 months", "now", "- 1 year")
  • max (chaîne, optionnel) - Date la plus récente sélectionnable. Mêmes options de format que min.

Boolean

Case à cocher Oui/Non. La valeur par défaut est false (décochée).

{
    "type": "Boolean",
    "data": {
        "label": "Termes et Conditions",
        "description": "J'accepte les termes et conditions" // Affiché à côté de la case à cocher
    }
}

SelectOne

Question à choix unique (boutons radio) - les utilisateurs sélectionnent une seule option.

{
    "type": "SelectOne",
    "data": {
        "label": "Quelle est votre couleur préférée ?",
        "required": "yes",
        "options": {
            "options": {
                "red": { "label": "Rouge" },
                "blue": { "label": "Bleu" },
                "green": { "label": "Vert" }
            },
            "displayOrder": ["red", "blue", "green"]
        }
    }
}

Utilisation de références de ressources :

{
    "type": "SelectOne",
    "data": {
        "label": "Choisissez une couleur",
        "options": { "$ref": "#/assets/color-options/data" }
    }
}

SelectMany

Question à choix multiples (cases à cocher) - les utilisateurs peuvent sélectionner plusieurs options.

{
    "type": "SelectMany",
    "data": {
        "label": "Quels systèmes d'exploitation utilisez-vous ?",
        "required": "yes",
        "options": {
            "options": {
                "windows": { "label": "Windows" },
                "macos": { "label": "macOS" },
                "linux": { "label": "Linux" }
            },
            "displayOrder": ["windows", "macos", "linux"]
        },
        "other": true, // Optionnel : ajoute une option "Autre" avec un champ de saisie de texte
        "minSelections": 1, // Optionnel : nombre minimum de sélections requises
        "maxSelections": 3 // Optionnel : nombre maximum de sélections autorisées
    }
}

Ranking

Classez plusieurs options par importance, préférence ou priorité. Les utilisateurs attribuent des scores à chaque option, généralement via des méthodes comparatives telles que le MaxDiff, la comparaison par paires, le tri par glisser-déposer ou l’allocation budgétaire.

{
    "type": "Ranking",
    "data": {
        "label": "Classez ces fonctionnalités par importance",
        "required": "yes",
        "options": {
            "options": {
                "performance": { "label": "Performance rapide" },
                "design": { "label": "Design épuré" },
                "price": { "label": "Prix abordable" },
                "support": { "label": "Support client 24/7" }
            },
            "displayOrder": ["performance", "design", "price", "support"]
        }
    }
}

IntervalScale

Échelle d’évaluation numérique avec une plage définie (ex. : 0-10 pour le NPS, 1-5 pour la satisfaction). Couramment utilisée pour :

  • Net Promoter Score (NPS) : échelle de 0 à 10
  • Évaluations de satisfaction : échelle de 1 à 5 ou de 1 à 7
  • Questions de probabilité : échelle de 0 à 10
{
    "type": "IntervalScale",
    "data": {
        "label": "Quelle est la probabilité que vous nous recommandiez à un ami ?",
        "required": "yes",
        "scale": {
            "start": 0, // Numéro de début de l'échelle
            "end": 10, // Numéro de fin de l'échelle
            "labels": {
                // Étiquettes pour les points de début et de fin (obligatoires)
                "start": "Pas du tout probable",
                "end": "Extrêmement probable"
            }
        }
    }
}

Cas d’utilisation courants :

// Net Promoter Score (NPS)
{
    "type": "IntervalScale",
    "data": {
        "label": "Quelle est la probabilité que vous nous recommandiez ?",
        "scale": {
            "start": 0,
            "end": 10,
            "labels": {
                "start": "Peu probable",
                "end": "Très probable"
            }
        }
    }
}

// Échelle de satisfaction à 5 points
{
    "type": "IntervalScale",
    "data": {
        "label": "Dans quelle mesure êtes-vous satisfait de notre service ?",
        "scale": {
            "start": 1,
            "end": 5,
            "labels": {
                "start": "Très insatisfait",
                "end": "Très satisfait"
            }
        }
    }
}

Affichage : Affiche une échelle horizontale avec des numéros cliquables. Les étiquettes apparaissent sous les points de début et de fin.

OrdinalScale

Échelle d’évaluation étiquetée où chaque point a une étiquette personnalisée. Idéal pour :

  • Échelles de Likert avec une formulation spécifique pour chaque point
  • Échelles d’accord (Fortement en désaccord → Fortement d’accord)
  • Échelles de fréquence (Jamais → Toujours)
  • Échelles d’évaluation personnalisées avec des étiquettes significatives
{
    "type": "OrdinalScale",
    "data": {
        "label": "Dans quelle mesure êtes-vous satisfait de votre poste ?",
        "required": "yes",
        "scale": {
            "labels": {
                "1": "Très insatisfait",
                "2": "Insatisfait",
                "3": "Neutre",
                "4": "Satisfait",
                "5": "Très satisfait"
            }
        }
    }
}

Cas d’utilisation courants :

// Échelle d'accord de type Likert
{
    "type": "OrdinalScale",
    "data": {
        "label": "Le produit a répondu à mes attentes.",
        "scale": {
            "labels": {
                "1": "Fortement en désaccord",
                "2": "En désaccord",
                "3": "Ni d'accord ni en désaccord",
                "4": "D'accord",
                "5": "Fortement d'accord"
            }
        }
    }
}

// Échelle de fréquence
{
    "type": "OrdinalScale",
    "data": {
        "label": "À quelle fréquence utilisez-vous notre produit ?",
        "scale": {
            "labels": {
                "1": "Jamais",
                "2": "Rarement",
                "3": "Parfois",
                "4": "Souvent",
                "5": "Toujours"
            }
        }
    }
}

Affichage : Affiche des boutons ou des options étiquetés. Chaque étiquette est affichée entièrement, rendant l’échelle auto-explicative.

IntervalScale vs OrdinalScale :

  • Utilisez IntervalScale lorsque les chiffres eux-mêmes ont une signification (0-10, 1-5).
  • Utilisez OrdinalScale lorsque vous avez besoin d’étiquettes personnalisées pour chaque point.
  • L’élément IntervalScale est plus compact ; l’élément OrdinalScale est plus descriptif.

Payment

Collecte les informations de paiement et traite les transactions. S’intègre avec les fournisseurs de paiement configurés dans les paramètres de votre sondage.

{
    "type": "Payment",
    "data": {
        "label": "Paiement",
        "required": "yes",
        "amount": {
            "value": 29.99,
            "currency": "USD"
        },
        "captureMethod": "automatic" // Optionnel : "immediate", "manual", ou "automatic"
    }
}

Propriétés :

  • amount (objet, obligatoire) - Montant du paiement avec value (nombre) et currency (code à 3 lettres, ex. : “USD”, “EUR”, “GBP”)
  • captureMethod (chaîne, optionnel) - Quand capturer le paiement :
    • "immediate" - Capturer le paiement immédiatement lors de la soumission du sondage
    • "manual" - Nécessite une capture manuelle via votre tableau de bord de paiement
    • "automatic" - Capture automatiquement lorsque le sondage est terminé (par défaut)

Remarque : Le traitement des paiements nécessite qu’un fournisseur de paiement soit configuré dans les paramètres de votre canal. Les devises et méthodes de paiement prises en charge dépendent de la configuration de votre fournisseur.


Variantes

Une question peut porter variants à côté de data : la même question, modifiée pour un segment. Une variante nomme une condition, écrite en ligne ou comme référence à un segment (une ressource condition, voir Segments), et ce qu’elle change ; la réponse arrive au même endroit quelle que soit la formulation :

{
    "type": "String",
    "data": { "label": "Quelle est la raison principale de votre note ?", "multiline": true },
    "variants": {
        "variants": {
            "low": {
                "condition": { "$ref": "#/assets/detractors/data" },
                "data": { "label": "Nous sommes désolés de l'apprendre. Quelle est la raison principale de votre note ?" }
            },
            "high": {
                "condition": { "$ref": "#/assets/promoters/data" },
                "data": { "label": "Quelle est la raison principale de votre note si élevée ?", "placeholder": "La chose que nous avons bien faite" },
                "extensions": { "highlight": false }
            }
        },
        "displayOrder": ["low", "high"]
    }
}
  • variants (objet) - Les variantes par id ; displayOrder liste les ids dans l’ordre où elles sont essayées. La première dont le segment s’applique est posée ; si aucune ne s’applique, la question est posée telle qu’elle est écrite. Un id absent de displayOrder est conservé mais jamais posé.
  • La condition d’une variante s’écrit comme toute autre condition : en ligne, ou comme $ref vers un segment, au sommet ou comme élément d’une chaîne. Les faits qu’elle lit doivent précéder la question. Un fait de la même page est décidé en direct, pendant que la personne répond : la formulation change sur place et une réponse déjà saisie reste. Un defaultValue ne s’applique que si la variante est décidée avant l’affichage de la page.
  • Les data et extensions d’une variante sont des merge patches sur ceux de la question : une clé définie remplace le champ, null le supprime, un objet imbriqué patche l’objet en dessous, un tableau remplace le tableau entier. Tout peut changer sauf type. La réponse à n’importe quelle variante est stockée sous l’id de la question elle-même ; une variante qui change le sens de la réponse (ses options, son échelle) le change donc pour toute la colonne. Une variante change la façon de poser la question, jamais ce qu’elle demande : chaque formulation ci-dessus demande la raison de la note, si bien que chaque réponse se lit correctement sous le libellé de la question elle-même.

Références JSON

Réduisez la duplication en référençant des composants réutilisables. Les références utilisent ce format :

{ "$ref": "[<emplacement>]#<chemin>" }
  • emplacement - URL vers le document source (vide = document actuel)
  • chemin - Chemin depuis la racine du document en utilisant des séparateurs /

Exemple - Duplication en ligne :

{
    "question-1": {
        "type": "SelectOne",
        "data": {
            "label": "Couleur préférée ?",
            "options": {
                "options": {
                    "red": { "label": "Rouge" },
                    "blue": { "label": "Bleu" }
                },
                "displayOrder": ["red", "blue"]
            }
        }
    },
    "question-2": {
        "type": "SelectOne",
        "data": {
            "label": "Couleur la moins appréciée ?",
            "options": {
                "options": {
                    "red": { "label": "Rouge" },
                    "blue": { "label": "Bleu" }
                },
                "displayOrder": ["red", "blue"]
            }
        }
    }
}

Mieux - En utilisant des ressources :

{
    "collections": {
        "main": {
            "elements": {
                "question-1": {
                    "type": "SelectOne",
                    "data": {
                        "label": "Couleur préférée ?",
                        "options": { "$ref": "#/assets/colors/data" }
                    }
                },
                "question-2": {
                    "type": "SelectOne",
                    "data": {
                        "label": "Couleur la moins appréciée ?",
                        "options": { "$ref": "#/assets/colors/data" }
                    }
                }
            },
            "displayOrder": ["question-1", "question-2"]
        }
    },
    "assets": {
        "colors": {
            "type": "options",
            "data": {
                "options": {
                    "red": { "label": "Rouge" },
                    "blue": { "label": "Bleu" }
                },
                "displayOrder": ["red", "blue"]
            }
        }
    }
}

Avantages :

  • Source de vérité unique
  • Maintenance plus facile
  • Meilleures comparaisons (diffs) pour le contrôle de version
  • Taille de fichier réduite

Logique Conditionnelle

La logique conditionnelle vous permet de créer des sondages dynamiques qui s’adaptent en fonction des réponses de l’utilisateur. Les conditions peuvent être utilisées de deux manières :

1. Conditions au niveau de la collection

Afficher ou masquer des pages entières en fonction de conditions. Si la condition d’une collection est évaluée à false, la page entière est sautée et l’exécution passe à la collection suivante.

{
    "collections": {
        "follow-up": {
            "name": "Questions de suivi",
            "condition": {
                "type": "condition",
                "fact": "questions/nps-score",
                "operator": "lt",
                "compare": { "value": 7 }
            },
            "elements": {
                /* ... */
            },
            "displayOrder": ["question-1"]
        }
    }
}

Dans cet exemple, la page « Questions de suivi » ne s’affiche que si le score NPS est inférieur à 7.

2. Éléments FlowControl

Contrôler le flux du sondage au sein d’une page en utilisant les éléments FlowControl. Lorsque la condition est évaluée à true, l’action spécifiée est exécutée.

Actions disponibles :

  • survey-finish - Termine le sondage immédiatement (saute toutes les pages restantes)
  • page-finish - Termine la page actuelle et passe à la suivante (saute les éléments restants sur la page actuelle)
{
    "type": "FlowControl",
    "data": {
        "condition": {
            "type": "condition",
            "fact": "questions/satisfaction",
            "operator": "eq",
            "compare": { "value": "very-satisfied" }
        },
        "action": {
            "type": "page-finish"
        }
    }
}

Remarque : Si aucune condition n’est fournie, l’action s’exécute toujours lorsque l’élément est atteint.

Structure d’une condition

Les conditions sont définies comme un arbre binaire avec deux types de nœuds :

1. Conditions de comparaison

Comparer un fait (réponse au sondage) à une valeur ou à un autre fait.

{
    "type": "condition",
    "fact": "questions/age",
    "operator": "gt",
    "compare": { "value": 18 }
}

Propriétés :

  • type - Toujours "condition" pour les comparaisons
  • fact (chaîne) - La référence de l’élément au format ‘collection-id/element-id’ dont la valeur doit être lue
  • operator (chaîne) - Opérateur de comparaison (voir les opérateurs ci-dessous)
  • compare (objet, optionnel) - Ce à quoi comparer :
    • { "value": <any> } - Comparer à une valeur littérale
    • { "fact": "<collection-id>/<element-id>" } - Comparer à la valeur d’un autre élément
    • Non requis pour les opérateurs comme "exists" ou "true"
  • not (booléen, optionnel) - Inverser le résultat (par défaut : false)

Opérateurs pris en charge par type d’élément :

Number, IntervalScale, OrdinalScale, Date :

  • "eq" - Égal à
  • "gt" - Supérieur à
  • "gte" - Supérieur ou égal à
  • "lt" - Inférieur à
  • "lte" - Inférieur ou égal à
  • "exists" - A une valeur (pas de compare nécessaire)

String :

  • "eq" - Égal à
  • "contains" - La chaîne contient la valeur
  • "exists" - A une valeur (pas de compare nécessaire)

Boolean :

  • "true" - La valeur est vraie (pas de compare nécessaire)
  • "exists" - A une valeur (pas de compare nécessaire)

SelectOne :

  • "eq" - Égal à une option spécifique
  • "in" - Est l’une des multiples options (la valeur de comparaison doit être un tableau de valeurs)
  • "exists" - A une valeur (pas de compare nécessaire)

SelectMany :

  • "eq" - Correspond exactement à l’ensemble des options
  • "exists" - A au moins une valeur (pas de compare nécessaire)

2. Conditions en chaîne

Combiner plusieurs conditions en utilisant des opérateurs logiques.

{
    "type": "all",
    "items": [
        {
            "type": "condition",
            "fact": "questions/age",
            "operator": "gt",
            "compare": { "value": 18 }
        },
        {
            "type": "condition",
            "fact": "questions/country",
            "operator": "eq",
            "compare": { "value": "US" }
        }
    ]
}

Propriétés :

  • type - Opérateur logique :
    • "all" - Toutes les conditions doivent être vraies (logique ET)
    • "any" - Au moins une condition doit être vraie (logique OU)
  • items (tableau) - Tableau de conditions (peuvent être des comparaisons ou des chaînes imbriquées)
  • not (booléen, optionnel) - Inverser le résultat de toute la chaîne
  • name (chaîne, optionnel) - Étiquette lisible par l’humain pour la documentation

Exemples

Sauter le sondage pour les clients satisfaits

{
    "type": "FlowControl",
    "data": {
        "condition": {
            "type": "condition",
            "fact": "questions/nps",
            "operator": "gte",
            "compare": { "value": 9 }
        },
        "action": {
            "type": "survey-finish"
        }
    }
}

Afficher la page uniquement pour une tranche d’âge spécifique

{
    "collections": {
        "teen-questions": {
            "name": "Questions pour les adolescents",
            "condition": {
                "type": "all",
                "items": [
                    {
                        "type": "condition",
                        "fact": "questions/age",
                        "operator": "gte",
                        "compare": { "value": 13 }
                    },
                    {
                        "type": "condition",
                        "fact": "questions/age",
                        "operator": "lt",
                        "compare": { "value": 20 }
                    }
                ]
            },
            "elements": {
                /* ... */
            }
        }
    }
}

Conditions imbriquées complexes

{
    "type": "any",
    "name": "Utilisateurs Premium ou gros dépensiers",
    "items": [
        {
            "type": "condition",
            "fact": "questions/membership",
            "operator": "eq",
            "compare": { "value": "premium" }
        },
        {
            "type": "all",
            "items": [
                {
                    "type": "condition",
                    "fact": "questions/total-spent",
                    "operator": "gt",
                    "compare": { "value": 1000 }
                },
                {
                    "type": "condition",
                    "fact": "questions/active-months",
                    "operator": "gte",
                    "compare": { "value": 6 }
                }
            ]
        }
    ]
}

Segments, une condition utilisée à plusieurs endroits

Une ressource condition est un segment : une condition avec un nom, écrite une fois sous assets et référencée partout où une condition est acceptée, au premier niveau ou comme élément d’une chaîne. Trois pages montrées au même public ne le disent alors qu’une fois, et modifier le segment modifie les trois.

{
    "collections": {
        "follow-up": {
            "name": "Suivi pour les détracteurs",
            "condition": { "$ref": "#/assets/detractors/data" },
            "elements": { /* ... */ },
            "displayOrder": ["question-1"]
        },
        "contact": {
            "name": "Pouvons-nous vous contacter",
            "elements": {
                "skip": {
                    "type": "FlowControl",
                    "data": {
                        "condition": {
                            "type": "all",
                            "not": true,
                            "items": [{ "$ref": "#/assets/detractors/data" }]
                        },
                        "action": { "type": "survey-finish" }
                    }
                }
            },
            "displayOrder": ["skip"]
        }
    },
    "assets": {
        "detractors": {
            "type": "condition",
            "name": "Détracteurs",
            "data": {
                "type": "condition",
                "fact": "questions/nps-score",
                "operator": "lte",
                "compare": { "value": 6 }
            }
        }
    }
}

Les data propres à un segment sont écrites en ligne : il ne peut pas référencer un autre segment. Les faits qu’il lit doivent précéder chaque endroit qui l’utilise, comme pour une condition en ligne.

Comparaison de deux faits

{
    "type": "condition",
    "fact": "questions/current-salary",
    "operator": "gt",
    "compare": { "fact": "questions/desired-salary" }
}

Utilisation de la propriété not

{
    "type": "condition",
    "fact": "questions/email-consent",
    "operator": "true",
    "not": true // Inverse le résultat : vrai lorsque email-consent n'est PAS vrai
}

Historique des Versions

Version Date Changements
1.0 15/11/2025 Élément de paiement
0.5 24/01/2025 Première version publique