Query Structure
Overview
A forecast query to the data endpoint is a JSON object that specifies:
What data you want (models, variables)
Where you want it (geographic filter)
When you want it (temporal filter)
How to process it (aggregation, grouping, weighting)
How to return it (format, ordering, pagination)
Basic Query Structure
{
"models": ["ept2"],
"geo": { ... },
"init_time": "latest",
"variables": [ ... ],
"prediction_timedelta": { ... },
...
}Required Parameters
Every query must include these three parameters:
models (required)
List of forecast model identifiers to query.
Type: array of strings
Minimum length: 1
Multiple models:
You can find an overview of the available models here.
geo (required)
Geographic filter specifying where to query data.
Type: object
Structure:
See Geographic Filtering section below for details.
init_time (required)
Forecast initialization time(s).
Type: string | array | object
Options:
Latest forecast:
Specific datetime (ISO 8601 format):
List of datetimes:
Time range:
Relative offsets (
"latest-N"):Returns the second-latest run.
"latest-2"returns the third-latest, etc.
model_runs (optional, alternative to models + init_time)
Per-model init_time specification. Use this when you want to query different models at different init times (for example, comparing the latest run of one model against a specific historical run of another). Cannot be combined with models/init_time.
Type: object mapping model identifier to an init_time spec (same shapes as init_time: "latest", "latest-N", integer offset, ISO datetime, list, or {start, end} range).
Geographic Filtering
The geo parameter supports six types of geographic queries.
1. Point Query
Query at specific coordinate(s).
Coordinates: [latitude, longitude]
Single point:
Multiple points:
Interpolation methods:
"nearest"(default): Returns value from nearest grid point"bilinear": Interpolates between 4 surrounding grid points
2. Bounding Box
Query a rectangular region.
Format: [[lat_min, lon_min], [lat_max, lon_max]]
This queries all grid points within the rectangle from (45°N, 5°E) to (50°N, 15°E).
3. Polygon
Query data within a custom polygon area.
Format: Array of [latitude, longitude] coordinates defining the polygon boundary.
Requirements:
Minimum 4 points (3 unique vertices + closing point)
Polygon should follow counter-clockwise ordering
4. Market Zone
Query data for predefined energy market zones.
Format: String or array of market zone codes
Multiple market zones:
5. Country
Query data for entire countries.
Format: ISO country codes
Multiple countries:
6. Points of Interest (POI)
Query at specific coordinates while attaching an id and/or label to each location, so the response carries the labels back.
Format: Array of objects with coordinates: [latitude, longitude] and optional id / label.
Use this instead of point when you need to track which row corresponds to which location without round-tripping the coordinates yourself.
Temporal Filtering
Control which forecast times to retrieve using temporal filters.
Forecast Time Concepts
init_time(required): When the forecast was generatedprediction_timedelta: How far ahead from init_time (lead time)time: Absolute forecast valid time (init_time + prediction_timedelta)
prediction_timedelta (optional)
Forecast lead time from initialization.
Units: Controlled by timedelta_unit parameter (default: "h" for hours)
Single value:
List of values:
Range:
If omitted: Returns all available lead times for the specified init_time(s).
time (optional)
Filter by absolute forecast valid time.
Single datetime:
List of datetimes:
Time range:
timedelta_unit (optional)
Units for prediction_timedelta and latest_min_prediction_timedelta.
Type: string
Default: "h" (hours)
Supported values:
"m","minute","minutes"- Minutes"h","hour","hours"- Hours"d","day","days"- Days
Example:
temporal_resolution (optional)
Resample lead times onto a regular cadence (specified in minutes), regardless of the model's native time step. Useful when you want a uniform cadence across the horizon — finer or coarser than the model produces natively — without listing leads manually.
Type: integer
Supported values: 15, 30, 60, 120, 180, 240, 300, 360 (minutes)
The behaviour depends on how the requested resolution compares to the model's native time step (e.g. 60 minutes for an hourly model):
Coarser than native (e.g.
180on an hourly model) — downsampling. The result is filtered to the requested cadence; intermediate native steps are dropped.Finer than native (e.g.
15on an hourly model) — linear interpolation. New lead times are inserted at the requested cadence and each variable is linearly interpolated between the surrounding native steps.Equal to native (e.g.
60on an hourly model) — no-op; the native steps are returned unchanged.
Downsampling example — coarsen an hourly model to every 3 hours:
This returns leads [0, 3, 6, 9, 12] (every 3 hours) inside the requested window.
Interpolation example — refine an hourly model to every 15 minutes:
This returns leads [0, 0.25, 0.5, 0.75, 1.0, …, 3.0]. Values at non-native leads (e.g. 0.25h) are linearly interpolated between the bracketing native steps — for temperature, a value of 294.7 at lead 0h and 297.0 at lead 1h yields 295.275 at lead 0.25h.
The requested cadence is interpreted in minutes and is independent of timedelta_unit (which only controls the units of prediction_timedelta in the request and response).
latest_min_prediction_timedelta (optional)
When using init_time: "latest", only include forecasts with at least this much lead time available.
Example:
This is useful when you need a minimum forecast horizon regardless of when the forecast was generated.
Variable Selection
variables (optional)
Weather variables to retrieve.
Type: array of strings
Default: All variables available for the selected models
Common variables:
air_temperature_at_height_level_2m- Temperature at 2m (Kelvin)wind_speed_at_height_level_10m- Wind speed at 10m (m/s)wind_speed_at_height_level_100m- Wind speed at 100m (m/s)relative_humidity_at_height_level_2m- Relative humidity (%)precipitation_amount_sum_1h- 1-hour accumulated precipitation (mm)surface_downwelling_shortwave_flux_sum_1h- 1-hour accumulated downwelling shortwave radiation (J/m²)air_pressure_at_mean_sea_level- Sea level pressure (Pa)And many more...
If omitted: Returns all variables common to the selected models.
Aggregation and Grouping
Aggregate data across space and/or time using group_by and aggregation.
Concept
group_by: Dimensions to preserve in the resultaggregation: How to aggregate values within each group
group_by (optional)
Dimensions to group by.
Type: array of strings
Supported dimensions:
"model"- Model identifier"init_time"- Forecast initialization time"time"- Forecast valid time"prediction_timedelta"- Lead time"latitude"- Latitude coordinate"longitude"- Longitude coordinate"point"- Groups by requested location and automatically addslatitudeandlongitudeto the result. The response includes apointindex column matching the order of the requested coordinates. Required to get one series per location when querying multiple points; also useful for ensemble models where you are interested in statistics per location (e.g. min, max, std)"ensemble_member"- Per-member dimension for ensemble models that expose individual members (e.g.ept2_e,ept2_hrrr,ecmwf_ens,ecmwf_aifs_ensemble). Use together withinclude_ensemble_members: true."market_zone"- Market zone (when using geo type market_zone)"country_key"- Country (when using geo type country_key)
Time transformations:
"time__to_start_of(hour)"or"hourly"- Grouped by start of hour"time__to_start_of(day)"or"daily"- Grouped by start of day"time__to_start_of(week)"or"weekly"- Grouped by start of week"time__to_start_of(month)"or"monthly"- Grouped by start of month"time__to_start_of(year)"or"yearly"- Grouped by start of yearSame transformations available for
init_time
Example - Average over all grid points for each valid time:
Example - Daily min & max:
aggregation (optional)
Aggregation functions to apply when grouping.
Type: array of objects or strings
Supported functions:
"avg"- Average"std"- Standard deviation"min"- Minimum"max"- Maximum"sum"- Sum"count"- Count"median"- Median"quantile"- Quantile (requires parameter)"argmin"- Returns the value of a column at the row where another variable is minimum (requires parameter for the column to return)"argmax"- Returns the value of a column at the row where another variable is maximum (requires parameter for the column to return)
Simple aggregation (all variables):
Multiple aggregations:
Variable-specific aggregation:
Parameterized aggregation (quantile):
Short syntax for parameterized aggregation:
argmin / argmax — return the value of one column at the row where another variable hits its min/max within the group. The parameter is the column to return; the variable is the column to find the extreme of. For example, argmin_(time)__air_temperature_at_height_level_2m returns the time at which temperature was minimum.
Common Aggregation Patterns
1. Spatial average at each timestep:
2. Daily maximum over a region:
3. Statistics at a specific location (for ensemble models, e.g. ept2_e):
To get the individual members instead of statistics, see include_ensemble_members below.
Weighting
Apply weighted aggregation based on capacity or population distribution.
weighting (optional)
Type: object
Structure:
Weighting types:
wind_capacity- Weight by installed wind power capacity (split into onshore and offshore where available)wind_capacity_combined- Weight by installed wind power capacity stored as a single combined value rather than split into onshore/offshore. Used for zones such asGBwhere capacity is not split. Withunit="mw"the output column iswind_total_mw.solar_capacity- Weight by installed solar power capacitypopulation- Weight by population density. Withunit="mw"andair_temperature_at_height_level_2m, returns a population-weighted load (demand) forecast in MW (load_mw).
unit (optional) — Defaults to "weather" (returns capacity-weighted raw weather values). Set to "mw" to apply power curves and return predicted megawatts. See Market Aggregates for the variable-to-output-column mapping in MW mode.
Example - Wind capacity-weighted average:
This computes the wind speed weighted by where wind turbines are located, giving more weight to regions with higher wind capacity and less weight to regions without production capacity.
Output Control
Control how results are formatted and returned.
include_ensemble_members (optional)
Return one row per ensemble member instead of the implicit ensemble mean.
Type: boolean
Default: false
Supported for ensemble models that expose individual members (for example ept2_e, ept2_hrrr, ept2_1_europa, ecmwf_ens, ecmwf_aifs_ensemble). When true, ensemble_member is added to group_by so aggregations run per member.
include_time (optional)
Include the forecast valid time column in results.
Type: boolean
Default: false
Result with include_time: true:
time_zone (optional)
IANA time zone for time formatting.
Type: string
Default: "UTC"
Common time zones:
"UTC"(default)"Europe/Berlin""America/New_York""America/Los_Angeles""Asia/Tokyo"
All time in responses are formatted in the specified time zone.
order_by (optional)
Sort results by specific dimensions.
Type: array of strings
Sortable dimensions:
"model""init_time""time""prediction_timedelta""latitude""longitude"Any variable name (e.g.,
"air_temperature_at_height_level_2m")
Constraints:
When using
group_by,order_bydimensions must be in thegroup_bylistRequired when using
pagination
pagination (optional)
Limit the number of results returned.
Type: object
Structure:
Example - Get first 1000 rows:
Example - Get next 1000 rows:
Best Practices
Performance
Use Arrow format for large queries: Set
?format=arrowin the URL for queries returning >10k rowsEnable streaming for very large queries: Add
&stream=truewith Arrow format for >100k rowsLimit prediction_timedelta range: Request only the lead times you need
Split historical data into multiple requests: Fetch data in chunks
Cost Optimization
Set
request_credit_limit: Prevents accidentally expensive queries. Pass as a query-string parameter, e.g.?request_credit_limit=200. Default:50for POST/data,5for GET endpoints.Aggregate when possible: Grouped queries accessing many points cost less per point
Select specific variables: Don't request all variables if you only need a few
Query Construction
Use
group_byfor spatial aggregates: When querying regions, group by time dimensionsInclude
timein results: Setinclude_time: truefor easier result interpretationSpecify time zones: Use
time_zoneto get times in your local timezoneOrder results: Use
order_byfor predictable result orderingTest with small queries first: Start with short time ranges, then expand
Validation and Errors
The API validates all query parameters and returns helpful error messages.
Common validation errors:
Invalid model: Model not available or not in your subscription
Variable not supported: Variable not available for selected model(s)
Invalid geo filter: Geographic coordinates out of range
Missing required parameter: Required field not provided
Insufficient credits: Not enough credits for the query
Response too large: Query returns too many rows
Next Steps
See examples: Check out the collection of example queries
Explore variables: Use
GET /v1/forecast/metato see all available models and variablesCheck availability: Use
GET /v1/forecast/available-forecaststo see available forecast timesCheck the OpenAPI docs: Endpoint & data models ready for you to try out
Last updated