Historical data & backtesting
Use historical queries when evaluating a decision or strategy with the information available at the time. Start with a customer API key and a product selected from the catalog.
Choose a selection mode
| Your question | Parameters |
|---|---|
| What was known at one specific time? | asOf |
| What was known one hour before each market gate? | relativeTo=gateClosure&leadMinutes=60 |
| What was known one hour before each delivery interval? | relativeTo=validTime&leadMinutes=60 |
Choose exactly one mode. The examples below use illustrative historical dates; choose dates on or after the selected catalog variant's historySince and check response coverage. Each request returns one page, with up to seven local days by default. Use the pagination example to retrieve a longer range.
A fixed as-of view
curl 'https://telescope.energy/api/v2/customer/forecasts/day-ahead-price-de-lu/data?deliveryFrom=2026-08-01&deliveryTo=2026-08-03&asOf=2026-07-31T10:00:00Z' \
-H "Authorization: Bearer $TELESCOPE_API_KEY"
For each local delivery day, this returns the latest forecast published by the specified time. asOf must include seconds and a UTC offset or Z, and cannot be in the future.
Constant-lead time series for backtesting
For one hour before each day's market gate:
curl 'https://telescope.energy/api/v2/customer/forecasts/day-ahead-price-de-lu/data?deliveryFrom=2026-08-01&deliveryTo=2026-08-31&relativeTo=gateClosure&leadMinutes=60' \
-H "Authorization: Bearer $TELESCOPE_API_KEY"
If a day's market gate is at 12:00 local, this selects the forecast available by 11:00. Use this mode only for a product with a gate-closure policy.
For one hour before each delivery interval:
curl 'https://telescope.energy/api/v2/customer/forecasts/afrr-activations-de/data?deliveryFrom=2026-08-01&deliveryTo=2026-08-31&relativeTo=validTime&leadMinutes=60' \
-H "Authorization: Bearer $TELESCOPE_API_KEY"
A 14:00 interval uses information available by 13:00; a 14:15 interval uses information available by 13:15. This mode also works for gate-closure products. The endpoint returns forecast inputs for your backtest, not strategy results or error metrics.
Interpret a relative response
values contains the forecast rows. intervals records the cutoff, availability and selected version for each expected timestamp. Join them using validTime; distinguish values using seriesKey and outputKey.
A relative day can use several forecast versions. All series and outputs for an individual interval come from the same version. Save interval version IDs and cutoffs if you need to reproduce the result.
Illustrative response excerpt for relativeTo=validTime&leadMinutes=60; fields and arrays are abbreviated:
{
"intervals": [
{ "validTime": "2026-07-31T22:00:00.000Z", "cutoffAt": "2026-07-31T21:00:00.000Z", "available": true, "forecastVersionId": "n97abc123", "releasedAt": "2026-07-31T20:50:00.000Z" },
{ "validTime": "2026-07-31T22:15:00.000Z", "cutoffAt": "2026-07-31T21:15:00.000Z", "available": false, "reason": "NO_VERSION_AT_AS_OF" }
],
"values": [
{ "validTime": "2026-07-31T22:00:00.000Z", "seriesKey": "positive", "outputKey": "p50", "value": 420.1 }
]
}
The second interval has no corresponding values. Preserve that gap; do not fill it with zero or a later forecast. For this example, the selected version covers the first interval only.
Check coverage
Later publications never fill a historical gap. Missing days or intervals remain marked unavailable. In relative responses, a day's available: true means at least one complete interval exists; check coverageRatio before assuming the entire day is present.
Use each unavailable interval's reason to distinguish missing publications, missing values and a decision cutoff that has not yet passed. The reference lists the exact reasons and selection rules.
Retrieve the full range
Follow pagination.nextCursor until it is null, sending the same product, date range and selection parameters on every page. A page contains complete local days. For 422 FORECAST_RANGE_TOO_COMPLEX, reduce limit; contact support if one day still fails.
This Python 3 example prints each page's values. Set TELESCOPE_OFFERING to a catalog slug or offering key. Replace the illustrative dates and choose one selection mode:
import json
import os
from urllib.parse import quote, urlencode
from urllib.request import Request, urlopen
offering = quote(os.environ["TELESCOPE_OFFERING"], safe="")
url = f"https://telescope.energy/api/v2/customer/forecasts/{offering}/data"
selection = {"relativeTo": "validTime", "leadMinutes": 60}
# For a market gate: {"relativeTo": "gateClosure", "leadMinutes": 60}
# For one fixed time: {"asOf": "2026-07-31T10:00:00Z"}
params = {"deliveryFrom": "2026-08-01", "deliveryTo": "2026-08-31", **selection}
while True:
request = Request(
url + "?" + urlencode(params),
headers={"Authorization": "Bearer " + os.environ["TELESCOPE_API_KEY"]},
)
with urlopen(request, timeout=30) as response:
page = json.load(response)
print(json.dumps(page["values"]))
cursor = page["pagination"]["nextCursor"]
if cursor is None:
break
params["cursor"] = cursor
For a stored backtest, also keep each page's coverage and version metadata (deliveryDays and, for relative queries, intervals).
See Versions & reproducibility for retrieving saved versions and Time and units for timestamp handling.