Passer au contenu principal
Ce tutoriel décrit comment demander les résultats d’expériences et déterminer les variations gagnantes à l’aide de l’Automation API. Il fait suite aux tutoriels précédents sur la création d’expériences, la modification de variations, l’association d’objectifs et de segments et le lancement d’expériences.

Prérequis

  • access_token
L’Automation API nécessite un access token. Récupérez le token de manière programmatique en suivant les instructions de la section Obtention d’un access token.
  • experimentId
L’experimentId est l’identifiant numérique de l’expérience dont vous souhaitez obtenir les résultats. Vous le trouverez dans l’URL de l’application Kameleoon lorsque vous consultez l’expérience (par exemple, https://app.kameleoon.com/.../experiments/188308/...). Pour les expériences de feature flag, l’ID est affiché dans le Rollout Planner.

Objectif

Le tutoriel utilise l’exemple d’expérience suivant :
Experiment_188308
Cette expérience, appelée Product Page Redesign, comprend deux variations en plus de la version originale : Redesign 1 (ID 828220) et Redesign 2 (ID 828221). Bien que l’expérience ait plusieurs objectifs, ce tutoriel se concentrera uniquement sur l’objectif principal, qui consiste à suivre les souscriptions d’assurance via le Click Tracking.
Le tutoriel s’applique également aux expériences Feature Flag ; cependant, utilisez les endpoints https://api.kameleoon.com/feature-flags/* au lieu de https://api.kameleoon.com/experiments/* :L’experimentId se trouve dans le Rollout Planner :

Fonctionnement de la récupération des résultats

La récupération des résultats se fait en deux étapes :
  1. Demander les résultats — envoyez une requête POST à /experiments/{experimentId}/results. La réponse retourne un hash dataCode, et non les résultats eux-mêmes.
  2. Interroger les résultats — envoyez une requête GET à /results?dataCode=<dataCode> pour récupérer les données réelles.
Les deux cas de l’étape 1 diffèrent uniquement par la méthode d’authentification : directement avec votre access token (Cas 1), ou via un shared token qui permet à des utilisateurs non authentifiés de consulter les résultats (Cas 2).

1. Récupérer le data code

Les principaux paramètres du corps de requête ci-dessous contrôlent le contenu du rapport. Pour la référence complète des paramètres, consultez l’endpoint Request experiment’s results.
ChampTypeDescription
goalsIdsinteger[]Objectifs à inclure. Passez [goalId] pour un objectif spécifique, [] pour tous les exclure, ou null pour tous les inclure.
referenceVariationIdstringLa variation à laquelle les autres seront comparées. Utilisez "0" pour la variation d’origine.
visitorDatabooleantrue compte les visiteurs uniques ; false (valeur par défaut) compte toutes les visites.
sequentialTestingbooleantrue active le sequential testing pour les intervalles de confiance.
conversionTypestringComptages utilisés pour les calculs de fiabilité. ALL_CONVERSION compte chaque événement de conversion par visiteur ; CONVERTED_VISITS compte chaque visite au plus une fois, quel que soit le nombre d’événements de conversion survenus pendant celle-ci.

Cas 1 : Récupérer les résultats directement

Envoyez une requête POST à l’endpoint Request experiment’s results en utilisant votre access token. Exemple :
curl -L -X POST 'https://api.kameleoon.com/experiments/188308/results' \
-H 'Content-Type: application/json' \
-H 'Accept: */*' \
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
--data-raw '{
  "visitorData": false,
  "sequentialTesting": true,
  "referenceVariationId": "0",
  "goalsIds": [279599]
}'
Réponse :
{"dataCode":"14443931880924098266207585267983330260134079899081739889989435434342588016765"}
Transmettez ce dataCode à l’étape 2 pour récupérer les résultats réels.

Cas 2 : Partager les résultats sans autorisation

Utilisez cette approche pour permettre à des utilisateurs de consulter les résultats sans access token — par exemple, pour partager une vue en direct des résultats avec une partie prenante.

1. Récupérer un SharedToken

Récupérez un SharedToken depuis l’endpoint Share experiment results. Cet endpoint accepte le même corps de requête que l’endpoint des résultats.
curl -L -X POST 'https://api.kameleoon.com/experiments/188308/results/share' \
-H 'Content-Type: application/json' \
-H 'Accept: */*' \
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
--data-raw '{
  "visitorData": false,
  "sequentialTesting": true,
  "referenceVariationId": "0",
  "goalsIds": [279599]
}'
Réponse :
{
    "method": "POST",
    "url": "https://api.kameleoon.com/experiments/188308/results",
    "path": "/experiments/188308/results",
    "headers": {
        "SharedToken": "eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE4NDQ5NDI5MTMsInNoYXJlZENvZGUiOiJhZmM1NzRjN2I4MjY4NTY3NzI2YjZhMDRhMTUxMjgyNjA3Zjk1ZGI4YjA1Y2RkZGY1ZDEwM2ExZDg5ZWM0MmZmIn0.oCECNm5mEhgIthc6eejo9BrfB7p8kEIrpoqtNb4JUiHK6nsxWHMvLc4hHYXCg3DgaBlVoKv6eEZHGty9c-VAoA",
        "Content-Type": "application/json"
    },
    "payload": {
        "visitorData": false,
        "sequentialTesting": true,
        "referenceVariationId": "0",
        "goalsIds": [279599]
    }
}

2. Récupérer le dataCode avec le SharedToken

Envoyez une requête POST à l’endpoint Request experiment’s results en utilisant le SharedToken obtenu dans la réponse précédente à la place d’un access token.
curl -L -X POST 'https://api.kameleoon.com/experiments/188308/results' \
-H 'Content-Type: application/json' \
-H 'Accept: */*' \
-H 'SharedToken: <SHARED_TOKEN>' \
--data-raw '{
  "visitorData": false,
  "sequentialTesting": true,
  "referenceVariationId": "0",
  "goalsIds": [279599]
}'
Réponse :
{"dataCode":"14443931880924098266207585267983330260134079899081739889989435434342588016765"}

2. Récupérer les résultats de l’expérience

Après avoir reçu le dataCode depuis l’un des cas ci-dessus, appelez l’endpoint result.
curl -L -X GET 'https://api.kameleoon.com/results?dataCode=14443931880924098266207585267983330260134079899081739889989435434342588016765'
Si la réponse retourne "status": "PENDING", le rapport est encore en cours de génération. Relancez la requête après un court délai jusqu’à ce que le statut soit "READY".
Réponse :
{
 "status": "READY",
 "data": {
  "dataCode": "14443931880924098266207585267983330260134079899081739889989435434342588016765",
  "variationData": {
   "_reference": {
    "breakdownData": {
     "_reference": {
      "intervalData": {},
      "generalData": {
       "visitCount": 126862,
       "visitorCount": 0,
       "goalsData": {
        "279599": {
         "conversionCount": 1898,
         "convertedVisitCount": 1898,
         "revenueCount": 235352.0,
         "convertedVisitorCount": 0,
         "revenuePerVisit": 1.86,
         "revenuePerVisitor": 0.0,
         "conversionRate": 0.014961138875313333,
         "averageCart": 124.0,
         "ratioValue": 0.0,
         "outlierBounds": {
          "lower": 0.1,
          "upper": 99.0
         }
        }
       }
      }
     }
    }
   },
   "828220": {
    "breakdownData": {
     "_reference": {
      "intervalData": {},
      "generalData": {
       "visitCount": 167938,
       "visitorCount": 0,
       "goalsData": {
        "279599": {
         "conversionCount": 7826,
         "convertedVisitCount": 7826,
         "revenueCount": 986076.0,
         "convertedVisitorCount": 0,
         "revenuePerVisit": 5.87,
         "revenuePerVisitor": 0.0,
         "reliability": 100.0,
         "improvementRange": {
          "min": 193.92,
          "max": 229.03,
          "half": 17.56
         },
         "improvementRate": 211.48,
         "conversionRate": 0.04660053114840001,
         "averageCart": 126.0,
         "ratioValue": 0.0,
         "continuousMetrics": {
          "conversions": {
           "reliability": 1.0,
           "improvementRate": 2.114771645178252,
           "halfInterval": 0.10445147824911348,
           "lowerBound": 2.0103201669291386,
           "upperBound": 2.219223123427365
          },
          "revenuePerVisit": {
           "reliability": 1.0,
           "improvementRate": 2.1650098975198366,
           "halfInterval": 0.10613617951119597,
           "lowerBound": 2.0588737180086407,
           "upperBound": 2.2711460770310326
          },
          "averageCart": null
         },
         "outlierBounds": {
          "lower": 0.1,
          "upper": 99.0
         }
        }
       }
      }
     }
    }
   },
   "828221": {
    "breakdownData": {
     "_reference": {
      "intervalData": {},
      "generalData": {
       "visitCount": 174194,
       "visitorCount": 0,
       "goalsData": {
        "279599": {
         "conversionCount": 1477,
         "convertedVisitCount": 1477,
         "revenueCount": 189056.0,
         "convertedVisitorCount": 0,
         "revenuePerVisit": 1.09,
         "revenuePerVisitor": 0.0,
         "reliability": 100.0,
         "improvementRange": {
          "min": -47.93,
          "max": -38.72,
          "half": 4.6
         },
         "improvementRate": -43.33,
         "conversionRate": 0.00847905209134643,
         "averageCart": 128.0,
         "ratioValue": 0.0,
         "continuousMetrics": {
          "conversions": {
           "reliability": 1.0,
           "improvementRate": -0.4332615877700786,
           "halfInterval": 0.027369693136479373,
           "lowerBound": -0.46063128090655797,
           "upperBound": -0.40589189463359926
          },
          "revenuePerVisit": {
           "reliability": 1.0,
           "improvementRate": -0.41497970350459723,
           "halfInterval": 0.028252586463462577,
           "lowerBound": -0.4432322899680598,
           "upperBound": -0.38672711704113466
          },
          "averageCart": null
         },
         "outlierBounds": {
          "lower": 0.1,
          "upper": 99.0
         }
        }
       }
      }
     }
    }
   }
  },
  "ventilationNames": null,
  "cupedDataByGoalId": {}
 }
}

3. Interpréter les résultats pour déterminer la variation gagnante

Les variations gagnantes doivent démontrer une grande fiabilité (supérieure à 95 %) et un taux d’amélioration positif par rapport à la variation de référence. La réponse JSON montre que Redesign 1 et Redesign 2 ont tous deux un taux de fiabilité de 100 %. Cependant, Redesign 1 a un taux d’amélioration de +211,48 % comparé au taux de -43,33 % de Redesign 2. Par conséquent, Redesign 1 est le gagnant. Redesign 1
"828220": {
    "breakdownData": {
     "_reference": {
      "intervalData": {},
      "generalData": {
       "visitCount": 167938,
       "visitorCount": 0,
       "goalsData": {
        "279599": {
         "conversionCount": 7826,
         "convertedVisitCount": 7826,
         "revenueCount": 986076.0,
         "convertedVisitorCount": 0,
         "revenuePerVisit": 5.87,
         "revenuePerVisitor": 0.0,
         "reliability": 100.0,
         "improvementRange": {
          "min": 193.92,
          "max": 229.03,
          "half": 17.56
         },
         "improvementRate": 211.48,
Redesign 2
"828221": {
    "breakdownData": {
     "_reference": {
      "intervalData": {},
      "generalData": {
       "visitCount": 174194,
       "visitorCount": 0,
       "goalsData": {
        "279599": {
         "conversionCount": 1477,
         "convertedVisitCount": 1477,
         "revenueCount": 189056.0,
         "convertedVisitorCount": 0,
         "revenuePerVisit": 1.09,
         "revenuePerVisitor": 0.0,
         "reliability": 100.0,
         "improvementRange": {
          "min": -47.93,
          "max": -38.72,
          "half": 4.6
         },
         "improvementRate": -43.33,

4. Filtrer les résultats d’expérience

Obtenez des résultats spécifiques en utilisant les paramètres breakdown et filters. Le paramètre breakdown organise les données selon une seule dimension (comme le navigateur, le système d’exploitation ou le jour de la semaine). Le paramètre filters restreint les données à un sous-ensemble de visiteurs avant l’application du breakdown.
Le paramètre breakdown accepte un seul objet par requête, pas un tableau. Pour comparer plusieurs dimensions, envoyez une requête par breakdown.

Formats de breakdown

La plupart des types de breakdown ne prennent qu’un champ type, par exemple :
"breakdown": {
  "type": "BROWSER"
}
Trois types de breakdown nécessitent des champs supplémentaires : INTERVAL — segmente les résultats par intervalle de temps. Associez "type": "INTERVAL" à un champ interval :
"breakdown": {
  "type": "INTERVAL",
  "interval": "DAY"
}
Le champ interval accepte HOUR, DAY, WEEK, MONTH ou YEAR. CUSTOM_DATUM — segmente les résultats par index de custom data. Associez "type": "CUSTOM_DATUM" à un champ index :
"breakdown": {
  "type": "CUSTOM_DATUM",
  "index": 3
}
CROSS_CAMPAIGN — segmente les résultats selon l’exposition à une autre expérience ou personnalisation. Fournissez au moins l’un des champs experiments ou personalizations :
"breakdown": {
  "type": "CROSS_CAMPAIGN",
  "experiments": [188309],
  "personalizations": []
}

Types de filters

Chaque objet filter requiert une chaîne type et un booléen include. Définissez include sur true pour restreindre les résultats aux visiteurs correspondants, ou false pour les exclure. Les champs supplémentaires dépendent du type :
typeChamps supplémentairesValeurs acceptées
BROWSERvalues (string[])CHROME, EDGE, FIREFOX, SAFARI, OPERA, OTHERS
DEVICE_TYPEvalues (string[])DESKTOP, TABLET, PHONE, OTHERS
OSvalues (string[])WINDOWS, MAC_OS, I_OS, LINUX, ANDROID, WINDOWS_PHONE, OTHERS
NEW_VISITORvisitorsType (string)NEW_VISITORS, RETURNING_VISITORS
ORIGIN_TYPEvalues (string[])SEO, SEM, AFFILIATION, EMAIL, DIRECT
SDKvalues (string[])JAVA, ANDROID, GO, DOTNET, PYTHON, RUBY, IOS, PHP, JAVASCRIPT, NODEJS, REACT, RUST, ELIXIR
DAY_OF_WEEKvalues (string[])SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
WEATHER_CODEvalues (string[])CLEAR_SKY, CLOUDS, RAIN, THUNDERSTORM, SNOW, HAIL, WIND, ATMOSPHERIC_DISTURBANCES
LANGUAGEvalues (string[])Codes de langue ISO 639-1 (par exemple, EN, FR, DE)
CUSTOM_DATUMcustomDataId (integer), value (string)Toute valeur de custom data
TARGETING_SEGMENTvalues (integer[])IDs de segments
GOAL_REACHEDgoalId (integer), index (integer), value (string)

Exemple : breakdown par navigateur filtré sur les nouveaux visiteurs

La requête suivante applique un breakdown par navigateur restreint aux nouveaux visiteurs en envoyant une requête POST à l’endpoint Request experiment’s results :
curl -L -X POST 'https://api.kameleoon.com/experiments/188308/results' \
-H 'Content-Type: application/json' \
-H 'Accept: */*' \
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
--data-raw '{
  "visitorData": true,
  "sequentialTesting": true,
  "breakdown": {
    "type": "BROWSER"
  },
  "referenceVariationId": "0",
  "filters": [
    {
      "type": "NEW_VISITOR",
      "visitorsType": "NEW_VISITORS",
      "include": true
    }
  ],
  "goalsIds": [279599]
}'
Après avoir reçu le dataCode, récupérez les résultats :
curl -L -X GET 'https://api.kameleoon.com/results?dataCode=14443931880924098266207585267983330260134079899081739889989435434342588016765'
Une requête réussie renvoie les résultats ventilés par navigateur. La réponse suit la même structure qu’à l’étape 2 ci-dessus, chaque type de navigateur (CHROME, FIREFOX, OTHERS, etc.) apparaissant comme clé dans breakdownData. La réponse suivante est tronquée pour plus de clarté :
{
  "status": "READY",
  "data": {
    "variationData": {
      "828221": {
        "breakdownData": {
          "OTHERS": {
            "intervalData": {},
            "generalData": {
              "visitCount": 0,
              "visitorCount": 587206,
              "goalsData": {
                "279599": {
                  "conversionCount": 5410,
                  "revenueCount": 692480.0,
                  "convertedVisitorCount": 5359,
                  "revenuePerVisitor": 1.18,
                  "reliability": 100.0,
                  "improvementRange": {
                    "min": -53.0,
                    "max": -48.7,
                    "half": 2.15
                  },
                  "improvementRate": -50.85,
                  "conversionRate": 0.009126269145751235,
                  "averageCart": 129.22,
                  "ratioValue": 0.0
                }
              }
            }
          },
          "CHROME": {
            "intervalData": {},
            "generalData": {
              "visitCount": 0,
              "visitorCount": 16,
              "goalsData": {
                "279599": {
                  "conversionCount": 0,
                  "revenueCount": 0.0,
                  "reliability": 50.0,
                  "improvementRate": 0.0,
                  "averageCart": 0.0,
                  "ratioValue": 0.0
                }
              }
            }
          }
        }
      }
    },
    "ventilationNames": null,
    "cupedDataByGoalId": {}
  }
}