> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kameleoon.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Retrieve JS and CSS code from experiments

> Retrieve JavaScript and CSS code from winning variations of paused or stopped experiments using the Automation API.

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](#build-the-filter) to retrieve code-based experiments that were paused or stopped since 2026.
2. [Retrieve the filtered experiments](#retrieve-the-filtered-experiments) using the [Get all experiments endpoint](/api-reference/experiment/get-all-experiments).
3. [Identify the winning variation](#find-the-winning-variation) by [retrieving the experiment results](./retrieving-experiment-results-using-the-automation-api).
4. [Retrieve the JS and CSS code](#retrieve-the-js-and-css-code) using the [Get a variation endpoint](/api-reference/variation/get-a-variation).

You can also find a [complete Python script](#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](/developer-docs/apis/automation-api-rest/get-started/get-started#1-obtain-an-access-token).

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

```json theme={null}
[
  {
    "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](/user-manual/experimentation/web-experimentation/manage-your-web-experiments/manage-your-experiments#access-the-experiments-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.

  <Frame>
    ![GraphQL filter example](https://storage.googleapis.com/kameleoon-storage-documentation/developers/images/apis/automation-api-rest/tutorials/retrieve-js-and-css-code-from-experiments/filter-graphql.png)
  </Frame>
</Tip>

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

```bash theme={null}
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

```json theme={null}
[
  {
    "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](./retrieving-experiment-results-using-the-automation-api).
2. Include the `mainGoalId` from the previous response.
3. Compare the `improvementRate` for each variation.

### Example request

```bash theme={null}
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](./retrieving-experiment-results-using-the-automation-api).

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

```bash theme={null}
curl -L "https://api.kameleoon.com/variations/1199120" \
-H "Accept: */*" \
-H "Authorization: Bearer <ACCESS_TOKEN>"
```

### Example response

```json theme={null}
{
  "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.

```python theme={null}
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()
```
