Zum Hauptinhalt springen
Dieses Tutorial beschreibt, wie Sie Experimentergebnisse anfordern und mithilfe der Automation API Gewinnervariationen ermitteln. Es folgt auf frühere Tutorials zum Erstellen von Experimenten, zum Ändern von Variationen, zum Verknüpfen von Zielen und Segmenten und zum Starten von Experimenten.

Voraussetzungen

  • access_token
Die Automation API erfordert ein Access Token. Rufen Sie das Token programmgesteuert ab, indem Sie den Anweisungen im Abschnitt Access Token abrufen folgen.
  • experimentId
Die experimentId ist die numerische Kennung des Experiments, dessen Ergebnisse Sie abrufen möchten. Sie finden sie in der URL der Kameleoon-App, wenn Sie das Experiment ansehen (zum Beispiel https://app.kameleoon.com/.../experiments/188308/...). Bei Feature-Flag-Experimenten wird die ID im Rollout Planner angezeigt.

Ziel

Das Tutorial verwendet das folgende Beispielexperiment:
Experiment_188308
Dieses Experiment, genannt Product Page Redesign, umfasst zwei Variationen zusätzlich zur Originalversion: Redesign 1 (ID 828220) und Redesign 2 (ID 828221). Obwohl das Experiment mehrere Ziele hat, konzentriert sich dieses Tutorial ausschließlich auf das Hauptziel, das darin besteht, Versicherungsabschlüsse über Click Tracking zu verfolgen.
Das Tutorial gilt auch für Feature Flag-Experimente; verwenden Sie jedoch die Endpoints https://api.kameleoon.com/feature-flags/* anstelle von https://api.kameleoon.com/experiments/*:Die experimentId befindet sich im Rollout Planner:

So funktioniert der Ergebnisabruf

Der Abruf von Ergebnissen erfolgt in zwei Schritten:
  1. Ergebnisse anfordern — POST an /experiments/{experimentId}/results. Die Antwort liefert einen dataCode-Hash, nicht die Ergebnisse selbst.
  2. Ergebnisse abfragen — GET /results?dataCode=<dataCode>, um die tatsächlichen Daten abzurufen.
Die beiden Fälle in Schritt 1 unterscheiden sich lediglich in der Art der Authentifizierung: entweder direkt mit Ihrem Access Token (Fall 1) oder über einen geteilten Token, der es nicht authentifizierten Benutzern ermöglicht, Ergebnisse anzusehen (Fall 2).

1. Den dataCode abrufen

Die folgenden wichtigen Body-Parameter steuern, was im Bericht enthalten ist. Die vollständige Parameterreferenz finden Sie im Request experiment’s results-Endpoint.
FeldTypBeschreibung
goalsIdsinteger[]Einzuschließende Ziele. Übergeben Sie [goalId] für ein bestimmtes Ziel, [], um alle auszuschließen, oder null, um alle einzuschließen.
referenceVariationIdstringDie Variation, mit der andere verglichen werden. Verwenden Sie "0" für die Originalvariation.
visitorDatabooleantrue zählt eindeutige Besucher; false (Standard) zählt alle Besuche.
sequentialTestingbooleantrue aktiviert Sequential Testing für Konfidenzintervalle.
conversionTypestringZählweise für die Zuverlässigkeitsberechnungen. ALL_CONVERSION zählt jedes Konversionsereignis pro Besucher; CONVERTED_VISITS zählt jeden Besuch höchstens einmal, unabhängig davon, wie viele Konversionsereignisse während des Besuchs stattgefunden haben.

Fall 1: Ergebnisse direkt abrufen

Senden Sie eine POST-Anfrage an den Request experiment’s results-Endpoint unter Verwendung Ihres Access Tokens. Beispiel:
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]
}'
Antwort:
{"dataCode":"14443931880924098266207585267983330260134079899081739889989435434342588016765"}
Übergeben Sie diesen dataCode an Schritt 2, um die tatsächlichen Ergebnisse abzurufen.

Fall 2: Ergebnisse ohne Autorisierung teilen

Verwenden Sie diesen Ansatz, um Benutzern das Anzeigen von Ergebnissen ohne Access Token zu ermöglichen – beispielsweise, um eine Live-Ansicht der Ergebnisse mit einem Stakeholder zu teilen.

1. Einen SharedToken abrufen

Rufen Sie einen SharedToken vom Share experiment results-Endpoint ab. Dieser Endpoint akzeptiert denselben Anfrage-Body wie der Ergebnis-Endpoint.
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]
}'
Antwort:
{
    "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. Den dataCode mit dem SharedToken abrufen

Senden Sie eine POST-Anfrage an den Request experiment’s results-Endpoint und verwenden Sie den SharedToken aus der vorherigen Antwort anstelle eines Access Tokens.
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]
}'
Antwort:
{"dataCode":"14443931880924098266207585267983330260134079899081739889989435434342588016765"}

2. Die Experimentergebnisse abrufen

Nachdem Sie den dataCode aus einem der beiden oben genannten Fälle erhalten haben, rufen Sie den result-Endpoint auf.
curl -L -X GET 'https://api.kameleoon.com/results?dataCode=14443931880924098266207585267983330260134079899081739889989435434342588016765'
Wenn die Antwort "status": "PENDING" zurückgibt, wird der Bericht noch erstellt. Wiederholen Sie die Anfrage nach einer kurzen Verzögerung, bis der Status "READY" lautet.
Antwort:
{
 "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. Die Ergebnisse interpretieren, um die Gewinnervariation zu ermitteln

Gewinnervariationen müssen eine hohe Zuverlässigkeit (über 95 %) und eine positive Verbesserungsrate gegenüber der Referenzvariation aufweisen. Die JSON-Antwort zeigt, dass sowohl Redesign 1 als auch Redesign 2 eine Zuverlässigkeitsrate von 100 % aufweisen. Redesign 1 hat jedoch eine Verbesserungsrate von +211,48 % im Vergleich zu -43,33 % von Redesign 2. Daher ist Redesign 1 der Gewinner. 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. Experimentergebnisse filtern

Erhalten Sie spezifische Ergebnisse, indem Sie die Parameter breakdown und filters verwenden. Der Parameter breakdown organisiert die Daten nach einer einzelnen Dimension (z. B. Browser, Betriebssystem oder Wochentag). Der Parameter filters beschränkt die Daten vor der Anwendung des Breakdowns auf eine Teilmenge der Besucher.
Der Parameter breakdown akzeptiert pro Anfrage ein einzelnes Objekt, kein Array. Um mehrere Dimensionen zu vergleichen, senden Sie eine Anfrage pro Breakdown.

Breakdown-Formate

Die meisten Breakdown-Typen benötigen nur ein type-Feld, zum Beispiel:
"breakdown": {
  "type": "BROWSER"
}
Drei Breakdown-Typen erfordern zusätzliche Felder: INTERVAL — segmentiert Ergebnisse nach einem Zeitintervall. Kombinieren Sie "type": "INTERVAL" mit einem interval-Feld:
"breakdown": {
  "type": "INTERVAL",
  "interval": "DAY"
}
Das Feld interval akzeptiert HOUR, DAY, WEEK, MONTH oder YEAR. CUSTOM_DATUM — segmentiert Ergebnisse nach dem Custom-Data-Index. Kombinieren Sie "type": "CUSTOM_DATUM" mit einem index-Feld:
"breakdown": {
  "type": "CUSTOM_DATUM",
  "index": 3
}
CROSS_CAMPAIGN — segmentiert Ergebnisse nach der Exposition gegenüber einem anderen Experiment oder einer Personalisierung. Geben Sie mindestens eines der Felder experiments oder personalizations an:
"breakdown": {
  "type": "CROSS_CAMPAIGN",
  "experiments": [188309],
  "personalizations": []
}

Filtertypen

Jedes Filterobjekt erfordert einen type-String und einen include-Boolean. Setzen Sie include auf true, um die Ergebnisse auf übereinstimmende Besucher zu beschränken, oder auf false, um sie auszuschließen. Die zusätzlichen Felder hängen vom type ab:
typeZusätzliche FelderZulässige Werte
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[])ISO 639-1 Sprachcodes (z. B. EN, FR, DE)
CUSTOM_DATUMcustomDataId (integer), value (string)Beliebiger Custom-Data-Wert
TARGETING_SEGMENTvalues (integer[])Segment-IDs
GOAL_REACHEDgoalId (integer), index (integer), value (string)

Beispiel: Browser-Breakdown gefiltert nach neuen Besuchern

Die folgende Anfrage wendet einen Browser-Breakdown an, der auf neue Besucher beschränkt ist, indem eine POST-Anfrage an den Request experiment’s results-Endpoint gesendet wird:
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]
}'
Nachdem Sie den dataCode erhalten haben, rufen Sie die Ergebnisse ab:
curl -L -X GET 'https://api.kameleoon.com/results?dataCode=14443931880924098266207585267983330260134079899081739889989435434342588016765'
Eine erfolgreiche Antwort gibt Ergebnisse zurück, die nach Browser aufgeschlüsselt sind. Die Antwort folgt derselben Struktur wie in Schritt 2 oben, wobei jeder Browsertyp (CHROME, FIREFOX, OTHERS usw.) als Schlüssel innerhalb von breakdownData dient. Die folgende Antwort ist zur Verdeutlichung gekürzt:
{
  "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": {}
  }
}