First forecast
Retrieve a published forecast with a customer API key. A successful request returns delivery-day versions and normalized values you can use in your application.
Prerequisites
Create a customer API key with catalog:read and forecasts:read, then set TELESCOPE_API_KEY. Use cURL, Python 3 (standard library) or TypeScript in a server-side runtime with fetch.
1. Discover a product
curl --fail-with-body 'https://telescope.energy/api/v2/customer/catalog' \
-H "Authorization: Bearer $TELESCOPE_API_KEY"
import json
import os
from urllib.request import Request, urlopen
request = Request(
"https://telescope.energy/api/v2/customer/catalog",
headers={"Authorization": "Bearer " + os.environ["TELESCOPE_API_KEY"]},
)
with urlopen(request, timeout=30) as response:
catalog = json.load(response)
for product in catalog["products"]:
print(product["slug"], product["title"])
const response = await fetch('https://telescope.energy/api/v2/customer/catalog', {
headers: { Authorization: `Bearer ${process.env.TELESCOPE_API_KEY}` },
})
if (!response.ok) throw new Error(await response.text())
const catalog = await response.json()
console.log(catalog.products)
Choose a returned slug for its default forecast, or a variants[].offeringKey for a specific variant. Read timezone, resolution, outputs and series from the selected variant. See the catalog reference for field details.
export TELESCOPE_OFFERING="<SLUG_OR_OFFERING_KEY_FROM_CATALOG>"
2. Retrieve the current forecast
Omit start to use the product's configured first delivery day. horizon=P1D requests one local delivery day; larger horizons must remain within the product limit.
curl --fail-with-body "https://telescope.energy/api/v2/customer/forecasts/$TELESCOPE_OFFERING/current?horizon=P1D" \
-H "Authorization: Bearer $TELESCOPE_API_KEY"
import json
import os
from datetime import datetime, timezone
from urllib.parse import quote
from urllib.request import Request, urlopen
offering = quote(os.environ["TELESCOPE_OFFERING"], safe="")
request = Request(
f"https://telescope.energy/api/v2/customer/forecasts/{offering}/current?horizon=P1D",
headers={"Authorization": "Bearer " + os.environ["TELESCOPE_API_KEY"]},
)
with urlopen(request, timeout=30) as response:
forecast = json.load(response)
for row in forecast["values"]:
instant = datetime.fromtimestamp(row["validTime"] / 1000, timezone.utc)
print(instant.isoformat(), row["seriesKey"], row["outputKey"], row["value"])
print("Keep these versions:", forecast["deliveryDays"])
const offering = encodeURIComponent(process.env.TELESCOPE_OFFERING!)
const response = await fetch(
`https://telescope.energy/api/v2/customer/forecasts/${offering}/current?horizon=P1D`,
{ headers: { Authorization: `Bearer ${process.env.TELESCOPE_API_KEY}` } },
)
if (!response.ok) throw new Error(await response.text())
const forecast = await response.json()
for (const row of forecast.values) {
console.log(new Date(row.validTime).toISOString(), row.seriesKey, row.outputKey, row.value)
}
console.log('Keep these versions:', forecast.deliveryDays)
3. Interpret the response
A successful request returns 200 OK. Values are sorted by validTime, seriesKey and outputKey. The following illustrative response uses a fixed historical date; fields and arrays are abbreviated. Your response uses the selected product and current delivery horizon.
{
"offering": "afrr-activations-de",
"resolution": "PT15M",
"outputs": [{ "key": "p50", "valueType": "number", "unit": "MW" }],
"deliveryDays": [
{ "deliveryDay": "2026-07-27", "forecastVersionId": "n97abc123", "status": "rolling", "coverageRatio": 1 }
],
"values": [
{ "validTime": "2026-07-26T22:00:00.000Z", "seriesKey": "negative", "outputKey": "p50", "value": 420.1 }
]
}
For example, the first row means:
| Field | Example | Interpretation |
|---|---|---|
validTime | 2026-07-26T22:00:00.000Z | Interval starts at 2026-07-26T22:00:00.000Z |
seriesKey | negative | The product's negative series |
outputKey | p50 | The quantile or point output identified in the catalog |
value | 420.1 | Forecast in the corresponding output's unit |
Keep every deliveryDays[].forecastVersionId alongside your decision so you can reproduce it later.
Check freshness
Each catalog variant’s historySince is the earliest published delivery date; latestReleasedAt is the most recent publication time as an RFC 3339 timestamp. Either can be null when no publication exists. These fields do not guarantee complete historical coverage or that every requested day is fresh: inspect each returned day's releasedAt and coverage.
Use webhooks to react to new publications.
If the request fails
The current endpoint is atomic across the requested days. If any day has not been published, the entire request returns 404 FORECAST_NOT_PUBLISHED. Check the horizon and publication availability; a catalog entry does not guarantee every requested day has a release. See Troubleshooting for authentication and other errors.
Explore in the playground
The Playground requires active Get Forecasts access and uses your signed-in account. Explore charts, tables or JSON for current and historical data, including relative interval coverage and provenance.
Choose Your API key to test key authentication and scopes. External Customer API requests require a key. See Troubleshooting if you reach the playground request limit.
Next steps
- Receive new forecast updates with Webhooks.
- Query historical data and constant-lead series.
- Understand forecast values and quantiles.
- Use the Public API for limited anonymous previews, rather than authenticated operational forecasts.