Skip to main content

Retrieve JS and CSS code from experiments

This guide explains how to retrieve the JavaScript and CSS code from winning variations of Developer (code-based) experiments that were paused or stopped since 2026.

To retrieve the code, complete the following steps:

  1. Build the filter to retrieve code-based experiments that were paused or stopped since 2026.
  2. Retrieve the filtered experiments using the Get all experiments endpoint.
  3. Identify the winning variation by retrieving the experiment results.
  4. Retrieve the JS and CSS code using the Get a variation endpoint.

You can also find a complete Python script implementing the workflow at the end of this guide.

Prerequisites

Before you use the Automation API, ensure that you have an access token.

To obtain a token, see the Authentication guide.

Build the filter

To filter experiments, use the filter query parameter. Filter the experiments based on the following criteria:

  • status: Set to PAUSED or STOPPED.
  • dateStatusModified: Set to greater than January 1, 2026.
  • type: Set to DEVELOPER.

Example filter

[
{
"field": "status",
"operator": "IN",
"parameters": ["PAUSED", "STOPPED"]
},
{
"field": "dateStatusModified",
"operator": "GREATER",
"parameters": ["2026-01-01T00:00:00"]
},
{
"field": "type",
"operator": "IN",
"parameters": ["DEVELOPER"]
}
]
tip

To generate a valid filter directly from the Experiment dashboard:

  1. Open your Experiment dashboard.
  2. Apply the desired filters using the dashboard UI.
  3. Open your browser's Developer Tools.
  4. Go to the Network tab.
  5. Search for the GetExperiments request.
  6. Open the corresponding GraphQL request and select the Payload tab.

You can copy the exact filter configuration generated by the interface and reuse it in the Automation API.

GraphQL filter example

Retrieve the filtered experiments

Pass the filter as a URL query parameter. Percent-encode the JSON filter before you add it to the URL.

Example request

curl -L "https://api.kameleoon.com/experiments?filter=%5B%7B%22field%22%3A%22status%22%2C%22operator%22%3A%22IN%22%2C%22parameters%22%3A%5B%22PAUSED%22%2C%22STOPPED%22%5D%7D%2C%7B%22field%22%3A%22dateStatusModified%22%2C%22operator%22%3A%22GREATER%22%2C%22parameters%22%3A%5B%222026-01-01T00%3A00%3A00%22%5D%7D%2C%7B%22field%22%3A%22type%22%2C%22operator%22%3A%22IN%22%2C%22parameters%22%3A%5B%22DEVELOPER%22%5D%7D%5D" \
-H "Accept: */*" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

Example response

[
{
"id": 344428,
"siteId": 31553,
"name": "TestJavascriptHelpDoc",
"type": "DEVELOPER",
"status": "STOPPED",
"mainGoalId": 396889,
"variations": [1199120, 1199121],
"dateStatusModified": "2026-02-09T11:23:31+0100",
"commonJavaScriptCode": "console.log(\"hello world\");",
"globalScript": "console.log(\"hello world\");"
}
]

From this response, note the following fields for the next steps:

  • id: The experiment ID.
  • mainGoalId: Required to retrieve the experiment results.
  • variations: The list of variation IDs.

Find the winning variation

To identify the winning variation, complete the following steps:

  1. Retrieve the experiment results. For more information, see Retrieve experiment results.
  2. Include the mainGoalId from the previous response.
  3. Compare the improvementRate for each variation.

Example request

curl -L -X POST "https://api.kameleoon.com/experiments/344428/results" \
-H "Content-Type: application/json" \
-H "Accept: */*" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
--data-raw '{
"visitorData": false,
"sequentialTesting": true,
"referenceVariationId": "0",
"goalsIds": [396889]
}'

Response

After submitting the request, you will receive a data code. Use this code to retrieve the results. For more information, see the retrieve experiment results guide.

Identify the winner

In the response data, locate the goalsData for each variation ID (for example, 1199120 and 1199121), ignoring the _reference (baseline) variation.

Compare the improvementRate of each variation. The variation with the highest positive improvementRate is the winner.

In this example:

  • 1199120 has an improvementRate of 26.57.
  • 1199121 has an improvementRate of -15.5.

Therefore, the winning variation is 1199120.

Retrieve the JS and CSS code

You can find experiment-level code in the following fields from your initial experiment response:

  • commonJavaScriptCode
  • commonCssCode
  • globalScript (custom experiment script)

To retrieve the variation-level code, use the Get a variation endpoint.

Example request

curl -L "https://api.kameleoon.com/variations/1199120" \
-H "Accept: */*" \
-H "Authorization: Bearer <ACCESS_TOKEN>"

Example response

{
"id": 804410,
"siteId": 24101,
"name": "Variation 1",
"jsCode": "(function() {})();",
"cssCode": "/* Add CSS code to this variation */",
"isJsCodeAfterDomReady": false
}

Locate the code

You can find the variation-level code in the following fields:

  • JavaScript code: jsCode
  • CSS code: cssCode

Complete Python script

The following script automates the full workflow to build the filter, retrieve the experiments, find the winning variation, and extract the code.

import requests
import json
import urllib.parse
import time
from datetime import datetime

# ==============================
# Configuration
# ==============================

ACCESS_TOKEN = "<ACCESS TOKEN>"
BASE_URL = "https://api.kameleoon.com"
DATE_FILTER = "2026-01-01T00:00:00"

HEADERS = {
"Accept": "*/*",
"Authorization": f"Bearer {ACCESS_TOKEN}"
}


# ==============================
# Step 1: Build and Encode Filter
# ==============================

def build_filter():
filter_payload = [
{
"field": "status",
"operator": "IN",
"parameters": ["PAUSED", "STOPPED"]
},
{
"field": "dateStatusModified",
"operator": "GREATER",
"parameters": [DATE_FILTER]
},
{
"field": "type",
"operator": "IN",
"parameters": ["DEVELOPER"]
}
]

filter_json = json.dumps(filter_payload)
encoded_filter = urllib.parse.quote(filter_json)
return encoded_filter


# ==============================
# Step 2: Retrieve Experiments
# ==============================

def get_filtered_experiments(encoded_filter):
url = f"{BASE_URL}/experiments?filter={encoded_filter}"
response = requests.get(url, headers=HEADERS)
response.raise_for_status()
return response.json()


# ==============================
# Step 3: Retrieve Experiment Results
# ==============================

def get_experiment_results(experiment_id, main_goal_id):
url = f"{BASE_URL}/experiments/{experiment_id}/results"

payload = {
"visitorData": False,
"sequentialTesting": True,
"referenceVariationId": "0",
"goalsIds": [main_goal_id]
}

response = requests.post(url, headers={
**HEADERS,
"Content-Type": "application/json"
}, json=payload)

response.raise_for_status()
data_code = response.json()["dataCode"]

experiment_results = requests.get(f"{BASE_URL}/results?dataCode={data_code}")

if experiment_results.json().get("status") != "READY":
print("Results not ready. Waiting 1s and retrying.")
time.sleep(1)
experiment_results = requests.get(f"{BASE_URL}/results?dataCode={data_code}")

return experiment_results.json()


# ==============================
# Step 4: Identify Winning Variation
# ==============================

def get_winning_variation(results_json, main_goal_id):
variation_data = results_json.get("data", {}).get("variationData", {})

best_variation_id = None
best_improvement = float("-inf")

for variation_id, variation_content in variation_data.items():

# Skip reference
if variation_id == "_reference":
continue

try:
goal_data = (
variation_content["breakdownData"]["_reference"]
["generalData"]["goalsData"][str(main_goal_id)]
)

improvement = goal_data.get("improvementRate", None)

if improvement is not None and improvement > best_improvement:
best_improvement = improvement
best_variation_id = variation_id

except KeyError:
continue

return best_variation_id, best_improvement


# ==============================
# Step 5: Retrieve Variation Code
# ==============================

def get_variation_code(variation_id):
url = f"{BASE_URL}/variations/{variation_id}"
response = requests.get(url, headers=HEADERS)
response.raise_for_status()
return response.json()


# ==============================
# Main Workflow
# ==============================

def main():
print("Building filter...")
encoded_filter = build_filter()

print("Retrieving experiments...")
experiments = get_filtered_experiments(encoded_filter)

if not experiments:
print("No experiments found.")
return

for experiment in experiments:
experiment_id = experiment["id"]
main_goal_id = experiment.get("mainGoalId")

print(f"\nProcessing experiment {experiment_id}...")

if not main_goal_id:
print("No main goal defined. Skipping.")
continue

print("Retrieving results...")
results = get_experiment_results(experiment_id, main_goal_id)

if results.get("status") != "READY":
print("Results not ready. Skipping.")
continue

winning_variation_id, improvement = get_winning_variation(results, main_goal_id)

if not winning_variation_id:
print("No winning variation found.")
continue

print(f"Winning variation: {winning_variation_id} (Improvement: {improvement}%)")

print("Retrieving JS and CSS code...")
variation_data = get_variation_code(winning_variation_id)

global_js_code = experiment.get("globalScript","")
common_css_code = experiment.get("commonCssCode","")
common_js_code = experiment.get("commonJavaScriptCode","")
js_code = variation_data.get("jsCode", "")
css_code = variation_data.get("cssCode", "")

print("\n--- Global JavaScript Code ---")
print(global_js_code)

print("\n--- Common JavaScript Code ---")
print(common_js_code)

print("\n--- Common CSS Code ---")
print(common_css_code)

print("\n--- JavaScript Code ---")
print(js_code)

print("\n--- CSS Code ---")
print(css_code)


if __name__ == "__main__":
main()