> For the complete documentation index, see [llms.txt](https://docs.jua.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.jua.ai/api-v2/query-engine/market-aggregates.md).

# Market Aggregates

### What are Market Aggregates for?

Market aggregates, especially used with weighting such as capacity weighting, are useful proxies to estimate how differences in forecasts - either between models or between different forecasts of the same model - impact energy production & consumption.

Imagine you are comparing the latest 12PM forecast of EPT against the 6 AM forecast. In Deckenpfronn, Germany, there is a huge difference in prediction for 100m wind speed. But since there is no wind park in Deckenpfronn this difference in wind speed will have no impact at the energy production at all. However, differences in wind speed at for example Reussenkoge Wind Farm, with a production capacity of over 250 MW, will have significant impacts on the energy output.

This is why we offer to compute capacity weighted averages for both solar and wind parameters. The averages are computed as

$$V\_{avg, weighted} =\sum\_i \dfrac{C\_i}{C\_{tot}} \cdot V\_i$$

Where $$V\_{i}$$ is the value of the variable (e.g. wind speed) at a specific location (e.g. a wind farm), $$C\_i$$ is the production capacity at that location and $$C\_{tot} = \sum\_i C\_i$$ is the total production capacity of the selected region.

### Output MW Mode

By adding `unit=mw` to the `GET /v1/forecast/market-aggregate` endpoint, the query engine applies generic power curves to weather forecasts and returns predicted **megawatts (MW)** instead of raw weather values. This is useful for comparing different models and quick MW estimates across many European zones.

{% hint style="info" %}
**Looking for actual production forecasts?** MW output here provides a model-specific forecast of **potential production** via power curves. For a forecast of **actual production**, use the [Power Forecast](/models-and-products/power-forecast.md) — an end-to-end model trained on real generation data, significantly more accurate. Currently available for Germany, France, United Kingdom, Belgium, and Netherlands (Solar, Wind).
{% endhint %}

MW mode is available on both endpoints:

* `GET /v1/forecast/market-aggregate?unit=mw&...`
* `POST /v1/forecast/data` with `weighting.unit=mw` in the body

MW mode:

* Activated by setting `unit=mw` (GET query parameter) or `weighting.unit="mw"` (POST body)
* Three weighting/variable combinations are supported:
  * `weighting=wind_capacity` with `wind_speed_at_height_level_100m` → returns `wind_onshore_mw`, `wind_offshore_mw` (or `wind_total_mw` for combined-only zones such as GB)
  * `weighting=solar_capacity` with `surface_downwelling_shortwave_flux_sum_1h` → returns `solar_mw`
  * `weighting=population` with `air_temperature_at_height_level_2m` → returns `load_mw` (electricity-demand forecast from a temperature-driven load curve)
* Restricts geo to `market_zone` or `country_key` (no polygon or bounding box)
* Only available for zones with fitted power curves (see MW-Capable Zones below)
* Weighting is auto-derived from the requested variable on the GET endpoint (wind speed → `wind_capacity`, shortwave flux → `solar_capacity`, 2m temperature → `population`)
* Wind and solar can be selected simultaneously on the GET endpoint; the backend issues separate queries per variable and merges
* When `merge_zones_or_countries` is enabled, MW values are summed across zones

#### Example: Wind MW Forecast

{% tabs %}
{% tab title="Curl" %}

```bash
curl -X GET "https://query.jua.ai/v1/forecast/market-aggregate\
?models=ept2\
&init_time=2025-10-22T00:00:00Z\
&weighting=wind_capacity\
&market_zones=DE\
&variables=wind_speed_at_height_level_100m\
&max_prediction_timedelta=72\
&unit=mw\
&include_time=true\
&format=json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Accept: application/json"
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://query.jua.ai/v1/forecast/market-aggregate"
headers = {
    "X-API-Key": "YOUR_API_KEY",
    "Accept": "application/json"
}
params = {
    "models": "ept2",
    "init_time": "2025-10-22T00:00:00Z",
    "weighting": "wind_capacity",
    "market_zones": ["DE"],
    "variables": ["wind_speed_at_height_level_100m"],
    "max_prediction_timedelta": 72,
    "unit": "mw",
    "include_time": True,
    "format": "json",
}

response = requests.get(url, headers=headers, params=params)
data = response.json()
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "model": ["ept2", "ept2", ...],
    "init_time": ["2025-10-22T00:00:00+00:00", ...],
    "prediction_timedelta": [0.0, 1.0, ...],
    "time": ["2025-10-22T00:00:00+00:00", ...],
    "market_zone": ["DE", "DE", ...],
    "wind_onshore_mw": [20109.78, 18485.41, ...],
    "wind_offshore_mw": [4933.67, 4880.13, ...]
}
```

{% endtab %}
{% endtabs %}

#### Example: Load (Demand) Forecast

A population-weighted electricity-demand forecast in MW, produced by applying a temperature-driven load curve to 2m air temperature.

{% tabs %}
{% tab title="Curl" %}

```bash
curl -X GET "https://query.jua.ai/v1/forecast/market-aggregate?models=ept2&init_time=latest&weighting=population&market_zones=DE&max_prediction_timedelta=72&unit=mw&include_time=true&format=json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Accept: application/json"
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://query.jua.ai/v1/forecast/market-aggregate"
headers = {
    "X-API-Key": "YOUR_API_KEY",
    "Accept": "application/json",
}
params = {
    "models": "ept2",
    "init_time": "latest",
    "weighting": "population",
    "market_zones": ["DE"],
    "max_prediction_timedelta": 72,
    "unit": "mw",
    "include_time": True,
    "format": "json",
}

response = requests.get(url, headers=headers, params=params)
data = response.json()
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "model": ["ept2", "ept2", ...],
    "init_time": ["2026-05-28T06:00:00+00:00", ...],
    "prediction_timedelta": [0.0, 1.0, ...],
    "time": ["2026-05-28T06:00:00+00:00", ...],
    "market_zone": ["DE", "DE", ...],
    "load_mw": [58525.5, 60100.2, ...]
}
```

{% endtab %}
{% endtabs %}

The same query expressed against `POST /v1/forecast/data`:

```python
payload = {
    "models": ["ept2"],
    "geo": {"type": "market_zone", "value": ["DE"]},
    "init_time": "latest",
    "variables": ["air_temperature_at_height_level_2m"],
    "prediction_timedelta": {"start": 0, "end": 72},
    "weighting": {"type": "population", "unit": "mw"},
    "group_by": ["model", "init_time", "prediction_timedelta", "time"],
    "aggregation": ["avg"],
    "include_time": True,
}
```

Load forecasts are available for \~48 zones today. Query `GET /v1/forecast/market-aggregate/mw-zones` and read the `load` key for the current list.

#### Example: Get Available MW Zones

```bash
curl -X GET "https://query.jua.ai/v1/forecast/market-aggregate/mw-zones" \
  -H "X-API-Key: YOUR_API_KEY"
```

```json
{
    "wind": ["AT", "BA", "BE", "BG", "CH", "CY", "CZ", "DE", ...],
    "wind_combined": ["GB"],
    "wind_onshore_only": ["AT", "BA", "BG", "CH", "CY", "CZ", ...],
    "solar": ["AT", "BA", "BE", "BG", "CH", "CY", "CZ", "DE", ...],
    "load": ["AL", "AT", "BA", "BE", "BG", "CH", "CY", "CZ", "DE", ...]
}
```

The keys break down as:

* `wind` — zones that support `wind_capacity` weighting; output may include `wind_onshore_mw` and/or `wind_offshore_mw`.
* `wind_combined` — zones (today: `GB` only) that store wind capacity as a single combined value rather than split into onshore/offshore; output is `wind_total_mw`.
* `wind_onshore_only` — subset of `wind` zones that only have onshore capacity data fitted; output is `wind_onshore_mw` only.
* `solar` — zones that support `solar_capacity` weighting; output is `solar_mw`.
* `load` — zones that have a fitted population-weighted load curve; output is `load_mw` when `weighting=population` and `unit=mw`.

#### MW-Capable Zones

The list is dynamic and grows over time as new zones are onboarded. Always query the `mw-zones` endpoint for the current set rather than hard-coding a list.

#### MW Column Names

When MW mode is enabled, output columns are renamed:

| Raw Column Name    | Display Name     | Unit | Weighting                            |
| ------------------ | ---------------- | ---- | ------------------------------------ |
| `wind_onshore_mw`  | Wind Onshore MW  | MW   | wind\_capacity                       |
| `wind_offshore_mw` | Wind Offshore MW | MW   | wind\_capacity                       |
| `wind_total_mw`    | Wind Total MW    | MW   | wind\_capacity (combined-only zones) |
| `solar_mw`         | Solar MW         | MW   | solar\_capacity                      |
| `load_mw`          | Load MW          | MW   | population                           |

### Variable-to-Weighting Mapping

When not using MW mode, the `weighting` field is applied based on the variable:

| Variable                                    | Weighting        |
| ------------------------------------------- | ---------------- |
| `wind_speed_at_height_level_100m`           | `wind_capacity`  |
| `surface_downwelling_shortwave_flux_sum_1h` | `solar_capacity` |
| `air_temperature_at_height_level_2m`        | `population`     |

### Aggregation Periods and Column Naming

Market aggregate responses use an `avg__` prefix on variable columns:

* Hourly: `avg__wind_speed_at_height_level_100m`
* Daily: `avg__wind_speed_at_height_level_100m`, time column becomes `time__to_start_of(day)`
* Weekly: `avg__wind_speed_at_height_level_100m`, time column becomes `time__to_start_of(week)`

In MW mode, columns use entirely different names (see MW Column Names above).

## Accessing Market Aggregates

There are two ways to access market aggregates:

* Making a request to `GET https://query.jua.ai/v1/forecast/market-aggregate`
* Using `POST https://query.jua.ai/v1/forecast/data` which allows selecting custom regions such as polygons and bounding boxes

### Using the \`market-aggregate\` endpoint

A convenient `GET` endpoint that allows fast and easy access to one or multiple market zones.

{% hint style="info" %}
The [Query Engine OpenAPI docs](https://query.jua.ai/docs) provide an interactive description of all endpoints
{% endhint %}

{% tabs %}
{% tab title="Curl" %}

```bash
curl -X GET "https://query.jua.ai/v1/forecast/market-aggregate\
?models=ept2\
&init_time=2025-10-22T00:00:00Z\
&weighting=wind_capacity\
&market_zones=DE\
&variables=wind_speed_at_height_level_100m\
&max_prediction_timedelta=72\
&include_time=true \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Accept: application/json"
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://query.jua.ai/v1/forecast/market-aggregate"
headers = {
    "X-API-Key": "YOUR_API_KEY",
    "Accept": "application/json"
}
params = {
    "models": "ept2",
    "init_time": "2025-10-22T00:00:00Z",
    "weighting": "wind_capacity",
    "market_zones": ["DE"],  # Germany
    "variables": ["wind_speed_at_height_level_100m"],
    "max_prediction_timedelta": 72, # hours
    "include_time": True,
}

response = requests.get(url, headers=headers, params=params)
data = response.json()
```

{% endtab %}

{% tab title="Javascript" %}

```javascript
const url = new URL("https://query.jua.ai/v1/forecast/market-aggregate");
url.searchParams.append("models", "ept2");
url.searchParams.append("init_time", "2025-10-22T00:00:00Z");
url.searchParams.append("weighting", "wind_capacity");
url.searchParams.append("market_zones", "DE");
url.searchParams.append("variables", "wind_speed_at_height_level_100m");
url.searchParams.append("max_prediction_timedelta", "2880");
url.searchParams.append("include_time", "true");

const response = await fetch(url, {
  method: "GET",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    Accept: "application/json",
  },
});

const data = await response.json();
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "model": [
        "ept2",
        "ept2",
        71 more entries...
    ],
    "init_time": ["2025-10-22T00:00:00Z", ...],
    "prediction_timedelta": [0, 1, ...., 72],
    "time": ["2025-10-22T00:00:00Z", "2025-10-22T01:00:00Z", ...],
    "avg__wind_speed_at_height_level_100m": [0.23, 0.51, ...]
}    
```

{% endtab %}
{% endtabs %}

### Using the generic \`data\` endpoint

While adding slightly more overhead to the query, the `data` endpoint provides more flexibility such as defining custom regions using polygons and bounding boxes. The example below is equivalent to the request to the `market-aggregate` endpoint above.

{% hint style="info" %}
Checkout the [examples](/api-v2/query-engine/examples.md) on how to use market aggregates with polygons
{% endhint %}

{% tabs %}
{% tab title="Python" %}

```python
import requests

url = "https://query.jua.ai/v1/forecast/data"
headers = {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
    "Accept": "application/json"
}
params = {
    "format": "json"
}
payload = {
    "models": ["ept2"],
    "geo": {
        "type": "market_zone",
        "value": ["DE"]
    },
    "variables": ["wind_speed_at_height_level_100m"],
    "init_time": "2025-10-22T00:00:00Z",
    "prediction_timedelta": {
        "start": 0,
        "end": 72
    },
    "weighting": {
        "type": "wind_capacity"
    },
    "group_by": ["model", "init_time", "prediction_timedelta", "time"],
}

response = requests.post(url, headers=headers, params=params, json=payload)
data = response.json()
```

{% endtab %}

{% tab title="Javascript" %}

```javascript
const url = "https://query.jua.ai/v1/forecast/data?format=json";

const payload = {
  models: ["ept2"],
  geo: {
    type: "market_zone",
    value: ["DE"],
  },
  variables: ["wind_speed_at_height_level_100m"],
  init_time: "2025-10-22T00:00:00Z",
  prediction_timedelta: {
    start: 0,
    end: 72,
  },
  weighting: {
    type: "wind_capacity",
  },
  group_by: ["model", "init_time", "prediction_timedelta", "time"],
};

const response = await fetch(url, {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
    Accept: "application/json",
  },
  body: JSON.stringify(payload),
});

const data = await response.json();
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "model": [
        "ept2",
        "ept2",
        71 more entries...
    ],
    "init_time": ["2025-10-08T00:00:00Z", ...],
    "prediction_timedelta": [0, 1, ...., 72],
    "avg__wind_speed_at_height_level_100m": [285.34, 285.91, ...],
}
```

{% endtab %}
{% endtabs %}

### Countries with Regional Zones

Some countries don't have a single zone code — use their regional zones instead:

| Country | Zone Codes                                                            |
| ------- | --------------------------------------------------------------------- |
| Italy   | IT-CNO, IT-CSO, IT-NO, IT-SAR, IT-SIC, IT-SO                          |
| Norway  | NO-NO1, NO-NO2, NO-NO3, NO-NO4, NO-NO5                                |
| Sweden  | SE-SE1, SE-SE2, SE-SE3, SE-SE4                                        |
| Denmark | DK-DK1, DK-DK2                                                        |
| Japan   | JP-CB, JP-CG, JP-HKD, JP-HR, JP-KN, JP-KY, JP-ON, JP-SK, JP-TH, JP-TK |

Countries with single zone codes: DE, FR, GB, NL, PL, ES, BE, AT, CH, CZ, PT, GR, IE


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.jua.ai/api-v2/query-engine/market-aggregates.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
