Embedding Explainable Machine Learning in Power Price Forecasts: Integrating SHAP and Energy API Time-Series for Transparent Trading Signals
Embedding Explainable Machine Learning (XML) into power price forecasting is no longer a “nice to have” for energy desks and risk teams — it is a requirement. Traders want to know exactly which drivers moved a signal; compliance wants auditable logic; engineers want features that stay stable under real-world publication cycles; and product teams need to turn all of this into APIs, dashboards, and alerts that customers can trust. This post shows how to integrate SHAP (SHapley Additive exPlanations) with unified, high-quality time-series from a single, normalized surface: Energy API. We will walk through a practical architecture for building transparent trading signals over electricity, gas, oil, coal, and carbon allowance markets, using one consistent JSON schema rather than juggling a dozen governmental portals.
The central idea is simple: you fetch the drivers that matter (e.g., TTF gas, EU ETS allowances, German day-ahead auction, Spanish intraday curves, Brent/WTI macro context, grid carbon intensity), train a robust model (e.g., gradient boosting), and then expose ranked SHAP attributions for every forecast. Thanks to Energy API’s unified interfaces — including intraday electricity curves where available — you can wire this system together in hours and keep it healthy with deterministic forecast lookups, status health checks, and consistent symbol metadata. We will cover the endpoints you need, provide complete JSON examples, and include code for aligning time-series, producing forecasts, and translating SHAP values into human-readable trade rationales.
Introduction
Without a unified data layer, explainable power forecasting quickly becomes a maintenance nightmare. Each data provider publishes with different schedules, time zones, week-ends, holiday rules, symbol naming, and formats. Your engineers spend weeks ETL’ing CSVs and scraping portals; your traders wonder why a feature disappeared last Friday; your dashboards show gaps precisely when markets are moving. Worse, the inconsistency undermines your explainability: if you can’t guarantee that TTF gas, EU ETS, and day-ahead power series are aligned and complete at inference time, your SHAP plots become unreliable.
Energy API eliminates this problem by aggregating official sources (like OMIE, ENTSO-E, EIA/FRED, and ESIOS) behind one normalized REST surface. Every commodity shares the same JSON schema, so you can fetch electricity, gas, oil, coal, and carbon allowance series with the same code paths. For XML workflows, this removes two of the biggest risks: inconsistent data shape and missing metadata. You focus on modeling and governance, not on plumbing.
In this guide, we will:
- Show how to pull multi-commodity features with consistent timestamps using a unified time-series endpoint.
- Demonstrate how to ingest intraday electricity curves for signal calibration and post-trade attribution.
- Build an explainable pipeline with XGBoost and SHAP that surfaces which drivers moved each forecast.
- Cover reliability techniques (health checks, retries, backoff, circuit breakers) using built-in endpoints like /status and /forecast.
Why Energy API
There are many raw data sources in energy — but only one place that presents them to developers with a single, predictable shape. Here are concrete advantages for teams building explainable forecasting and trading systems:
- One normalized REST surface: Fetch OMIE day-ahead, ENTSO-E intraday, EIA/FRED macro series, ESIOS PVPC retail references, and ETS allowances with the same field names and response shapes. Your feature pipeline code path becomes uniform and testable across more than 39 symbols and six commodity categories.
- Multi-commodity joins with one call: Use the /latest or /timeseries endpoints to retrieve electricity, gas, oil, coal, and carbon allowance signals together. This greatly simplifies cross-asset explanatory modeling — SHAP values are only as good as the consistent features you feed them.
- Intraday electricity curves: Where sources publish them, you can pull 15-minute or hourly curves. This unlocks post-trade decompositions (e.g., “Which hours in the DE day-ahead curve were most sensitive to EUA_CO2 and TTF_GAS yesterday?”) with precise temporal granularity.
- Deterministic day-ahead lookups: The /forecast endpoint returns already-published auction results for day-ahead power. Your backtests remain reproducible and your real-time routes become robust because you are not guessing or scraping — you are retrieving canonical, timestamped values.
Energy API’s ergonomics mean you can experiment fast, standardize on a core feature set, and then scale with confidence. Traders get faster iteration; governance teams get transparent inputs and consistent metadata; developers avoid bespoke parsers and one-off cron jobs.
Quick Start
All examples below use the base URL:
https://energy-api.com/api/v1
Requests are simple GETs or POSTs with query parameters. Below is a first request that fetches the most recent price for three symbols across different commodities — oil (Brent), gas (TTF), and carbon (EU ETS allowances). This illustrates the normalized multi-commodity surface in a single call.
curl -G https://energy-api.com/api/v1/latest \
--data-urlencode "symbols=BRENT_CRUDE,TTF_GAS,EUA_CO2" \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON response:
{
"success": true,
"date": "2026-06-11",
"base": "MIXED",
"rates": {
"BRENT_CRUDE": 74.82,
"TTF_GAS": 38.15,
"EUA_CO2": 67.40
},
"dates": {
"BRENT_CRUDE": "2026-06-11",
"TTF_GAS": "2026-06-11",
"EUA_CO2": "2026-06-11"
},
"currencies": {
"BRENT_CRUDE": "USD",
"TTF_GAS": "EUR",
"EUA_CO2": "EUR"
}
}
Field explanations:
- success: Boolean indicating call status.
- date: The most recent consolidated date for the returned symbols.
- base: Currency context if unified; MIXED indicates multiple native currencies are returned.
- rates: The latest numeric values keyed by symbol.
- dates: Per-symbol last publication dates (essential for aligning features by their own calendar).
- currencies: Per-symbol currency metadata (critical for normalization and P&L, even if you keep native currencies).
Why this matters for explainability: You can enrich each forecast with the exact publication dates and currencies used. Auditors and risk managers love that clarity; your SHAP attributions reflect real, timestamped inputs.
Architecture for Explainable Power Forecasting
A robust explainable pipeline balances three concerns: data fidelity, model veracity, and operational reliability. Below is a reference architecture aligned with Energy API’s endpoints.
- Feature ingestion: Use /symbols to discover metadata and /timeseries to load multi-commodity training features for your lookback window (e.g., 2 years of EU power and macro drivers). For intraday features and validation, use /electricity/hourly for the target market (e.g., DE, ES) on specific dates.
- Target construction: For day-ahead auction results, retrieve next-published prices via /forecast. For realized retail references in Spain, integrate /electricity/pvpc for calibration vs. consumer-side proxies.
- Sanity checks and fallbacks: Monitor provider pipelines using /status. Build retries with exponential backoff and simple circuit breakers around any temporarily degraded provider. Use /historical for exact “as-of” values when you need backtesting snapshots.
- Explainability layer: Train a gradient boosted tree model (e.g., XGBoost, LightGBM) using the standardized features. Compute SHAP values on predictions and attach them to every forecast event you publish internally (and optionally externally to clients).
- Attribution surfaces: Keep per-commodity feature groups so SHAP contributions can be explained in business language: “Gas added +€3.10/MWh due to increase in TTF; EUA added +€1.50/MWh; Brent was neutral.”
Energy API gives you the reliable surface area to implement each step with deterministic requests and consistent response shapes.
Core Endpoints for Explainable Forecasts
1) Discover features and metadata: GET /symbols
Purpose: List all available symbols, filterable by category and provider, so you can programmatically assemble and maintain your feature registry.
Key params:
- category: gas | electricity | oil | coal | carbon_intensity | carbon
- base: Optional currency filter
- provider: Optional source filter (e.g., omie, entso-e, eia, fred, esios)
curl -G https://energy-api.com/api/v1/symbols \
--data-urlencode "category=electricity" \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON response:
{
"success": true,
"count": 5,
"symbols": [
{
"symbol": "OMIE_ES_DA",
"name": "OMIE Spain Day-Ahead",
"category": "electricity",
"country_code": "ES",
"currency_code": "EUR",
"frequency": "daily",
"description": "OMIE day-ahead auction clearing price."
},
{
"symbol": "EPEX_DE_DA",
"name": "EPEX Germany Day-Ahead",
"category": "electricity",
"country_code": "DE",
"currency_code": "EUR",
"frequency": "daily",
"description": "Day-ahead auction for Germany."
},
{
"symbol": "PVPC_ES_2TD",
"name": "Spain PVPC 2.0TD Retail Reference",
"category": "electricity",
"country_code": "ES",
"currency_code": "EUR",
"frequency": "hourly",
"description": "ESIOS PVPC hourly reference price."
},
{
"symbol": "AEMO_NSW1",
"name": "AEMO New South Wales",
"category": "electricity",
"country_code": "AU",
"currency_code": "AUD",
"frequency": "5min",
"description": "Spot prices for NSW region."
},
{
"symbol": "EPEX_DE_ID",
"name": "EPEX Germany Intraday",
"category": "electricity",
"country_code": "DE",
"currency_code": "EUR",
"frequency": "hourly",
"description": "Aggregated intraday curve where available."
}
]
}
How to use it:
- Generate a registry of candidate features by category and country for your model runs.
- Attach metadata (currency_code, frequency) so ingestion hubs can resample appropriately.
- Maintain curated feature sets for each trading book with strong typing and documentation.
2) Build multi-commodity training data: GET /timeseries
Purpose: Retrieve historical time-series between two dates for multiple symbols, keyed by date — ideal for modeling and charting.
Key params:
- start, end: YYYY-MM-DD
- symbols: Comma-separated list (e.g., EPEX_DE_DA,TTF_GAS,EUA_CO2,BRENT_CRUDE)
- base: Optional currency filter (if you prefer to restrict to a currency context)
curl -G https://energy-api.com/api/v1/timeseries \
--data-urlencode "start=2025-01-01" \
--data-urlencode "end=2025-03-31" \
--data-urlencode "symbols=EPEX_DE_DA,TTF_GAS,EUA_CO2,BRENT_CRUDE" \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON response:
{
"success": true,
"base": "MIXED",
"start_date": "2025-01-01",
"end_date": "2025-03-31",
"rates": {
"EPEX_DE_DA": {
"2025-01-02": 61.20,
"2025-01-03": 58.75
},
"TTF_GAS": {
"2025-01-02": 46.80,
"2025-01-03": 47.10
},
"EUA_CO2": {
"2025-01-02": 69.50,
"2025-01-03": 70.10
},
"BRENT_CRUDE": {
"2025-01-02": 76.30,
"2025-01-03": 75.90
}
},
"frequencies": {
"EPEX_DE_DA": "daily",
"TTF_GAS": "daily",
"EUA_CO2": "daily",
"BRENT_CRUDE": "daily"
},
"currencies": {
"EPEX_DE_DA": "EUR",
"TTF_GAS": "EUR",
"EUA_CO2": "EUR",
"BRENT_CRUDE": "USD"
}
}
Field explanations:
- rates: Dictionary-of-dictionaries holding date-keyed values for each symbol.
- frequencies: Frequency metadata per symbol that guides resampling (daily vs hourly alignment).
- currencies: Currency per symbol, crucial for normalization and risk aggregation.
Best practice: Use the per-symbol frequency to resample upstream, preserving audit trace. For example, you can hold native currencies for modeling and only convert in P&L layers, reducing distortion in SHAP attributions.
3) Ingest intraday electricity curves: GET /electricity/hourly
Purpose: Retrieve full intraday (or hourly) curves for a given electricity symbol and date. This is essential for calibration, scenario analysis, and hour-by-hour SHAP attribution.
Key params:
- symbol: e.g., OMIE_ES_DA or EPEX_DE_ID
- date: YYYY-MM-DD (the day for which the curve is published)
curl -G https://energy-api.com/api/v1/electricity/hourly \
--data-urlencode "symbol=OMIE_ES_DA" \
--data-urlencode "date=2025-09-15" \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON response:
{
"success": true,
"symbol": "OMIE_ES_DA",
"date": "2025-09-15",
"currency": "EUR",
"granularity": "hourly",
"curve": [
{"timestamp": "2025-09-15T00:00:00+02:00", "price": 72.10},
{"timestamp": "2025-09-15T01:00:00+02:00", "price": 69.80},
{"timestamp": "2025-09-15T02:00:00+02:00", "price": 67.45}
// ... up to 24 points (or 96 if 15-min where the source provides)
]
}
How to use it:
- Train hour-ahead or day-ahead models with hour-specific features (e.g., solar forecast proxies using PVPC_ES_2TD, gas/oil/carbon context, and previous intraday shapes).
- Attribute forecasts post-trade using SHAP at the hour-level: “Hour 19 gained +€8/MWh from carbon and +€2/MWh from gas.”
- Detect anomalies or publication lags by comparing expected curve length to granularity metadata.
4) Deterministic day-ahead lookups: GET /forecast
Purpose: Retrieve the next published day-ahead auction price for auction-sourced electricity symbols. This endpoint is not a predictive model — it is a deterministic lookup of published results. It is perfect for operational triggers and model target alignment.
Key params:
- symbol: Auction-sourced electricity symbol (e.g., OMIE_ES_DA, EPEX_DE_DA).
curl -G https://energy-api.com/api/v1/forecast \
--data-urlencode "symbol=EPEX_DE_DA" \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON response:
{
"success": true,
"symbol": "EPEX_DE_DA",
"publish_date": "2025-09-14",
"target_date": "2025-09-15",
"currency": "EUR",
"value": 63.45,
"source": "EPEX",
"note": "Next published auction result."
}
Use cases:
- Align the target variable for supervised training: The target_date tells you the delivery day for which the published price applies.
- Operational gating: Trigger backfills and SHAP refresh jobs when publish_date changes.
- Sanity checks: For any given trading day, confirm that your internal model’s out-of-sample prediction corresponds to the correct, officially published value.
5) Changes over time: GET /fluctuation
Purpose: Quickly compute start/end values and percentage changes over a period for one or more symbols. Great for feature engineering (rate-of-change) and for contextual explanations in SHAP narrative layers.
Key params:
- start, end: YYYY-MM-DD
- symbols: One or more, comma-separated
curl -G https://energy-api.com/api/v1/fluctuation \
--data-urlencode "start=2025-08-01" \
--data-urlencode "end=2025-09-15" \
--data-urlencode "symbols=TTF_GAS,EUA_CO2" \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON response:
{
"success": true,
"period": {
"start": "2025-08-01",
"end": "2025-09-15"
},
"symbols": {
"TTF_GAS": {
"start_value": 41.20,
"end_value": 36.20,
"change": -5.00,
"change_pct": -12.14
},
"EUA_CO2": {
"start_value": 71.10,
"end_value": 67.40,
"change": -3.70,
"change_pct": -5.20
}
}
}
Practical uses:
- Features: rolling_change_7d, rolling_change_30d, and regime flags for model training.
- Explanations: “EUA_CO2 fell 5.2% over the lookback; SHAP attributes -€1.1/MWh to carbon” — now you can connect directional shifts to quantitative attributions.
6) Candles for volatility context: GET /ohlc
Purpose: Retrieve weekly/monthly/quarterly OHLC candles for volatility-aware features. These are useful for risk-sensitive signals and for adding persistence measures to your explainability layer.
Key params:
- symbols: One or more
- period: weekly | monthly | quarterly
- start, end: Optional range filters
curl -G https://energy-api.com/api/v1/ohlc \
--data-urlencode "symbols=BRENT_CRUDE,TTF_GAS" \
--data-urlencode "period=monthly" \
--data-urlencode "start=2025-01-01" \
--data-urlencode "end=2025-06-30" \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON response:
{
"success": true,
"symbols": {
"BRENT_CRUDE": [
{"period": "2025-01", "open": 76.30, "high": 79.50, "low": 72.90, "close": 75.10, "data_points": 21},
{"period": "2025-02", "open": 75.20, "high": 80.10, "low": 74.00, "close": 77.40, "data_points": 20}
],
"TTF_GAS": [
{"period": "2025-01", "open": 46.80, "high": 50.20, "low": 45.10, "close": 47.90, "data_points": 22},
{"period": "2025-02", "open": 48.10, "high": 51.00, "low": 46.00, "close": 49.40, "data_points": 20}
]
}
}
How to use it:
- Feature: realized volatility via high-low or ATR-like proxies for macro sensitivity in power prices.
- Explainability: contextual text — “Gas volatility compressed in February; model reduced sensitivity to TTF by 20%.”
7) Electricity category convenience endpoints
Besides hourly curves and forecasts, the electricity category has specialized endpoints that frequently appear in prediction and attribution stacks:
- /electricity/latest: Quickly scan the latest values for all electricity symbols, optionally filtered by country.
- /electricity/pvpc: Retrieve Spanish PVPC hourly reference prices for a given date; useful as a consumer-side proxy feature in Iberian modeling or for non-hedgeable retail contexts.
Example cURL for PVPC:
curl -G https://energy-api.com/api/v1/electricity/pvpc \
--data-urlencode "date=2025-09-15" \
--data-urlencode "api_key=YOUR_API_KEY"
Illustrative JSON:
{
"success": true,
"date": "2025-09-15",
"currency": "EUR",
"hourly": [
{"timestamp": "2025-09-15T00:00:00+02:00", "price": 0.155},
{"timestamp": "2025-09-15T01:00:00+02:00", "price": 0.149}
// ...
]
}
Use PVPC as a validation target, a sanity check for consumer-facing apps, or a feature reflecting downstream retail pass-through dynamics.
8) Other categories for cross-asset drivers
Power is shaped by fuels, carbon policy, and global macro. These convenience endpoints give you simple access to canonical drivers:
- /gas/latest: TTF_GAS (EU) and HENRY_HUB (US) in one call.
- /emissions/latest: EUA_CO2 for EU ETS allowances.
- /coal/latest: COAL_ROTTERDAM (API2) and COAL_NEWCASTLE.
- /carbon-intensity: Grid carbon intensity per country in gCO2eq/kWh, useful for sustainability scoring and eco-intensity overlays.
This breadth lets you quantify chains like “TTF up + EUA up → DE day-ahead up,” and present SHAP decompositions that map exactly to trader intuition and risk factor models.
9) Point-in-time lookups: GET /historical
Purpose: Retrieve prices for all symbols on a specific historical date, with built-in rules for non-publishing days (it returns the most recent value before the date). This is ideal for backtesting with realistic as-of snapshots.
curl -G https://energy-api.com/api/v1/historical \
--data-urlencode "date=2025-09-15" \
--data-urlencode "symbols=BRENT_CRUDE,TTF_GAS" \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON response:
{
"success": true,
"date": "2025-09-15",
"base": "MIXED",
"rates": {
"BRENT_CRUDE": 71.45,
"TTF_GAS": 36.20
},
"currencies": {
"BRENT_CRUDE": "USD",
"TTF_GAS": "EUR"
}
}
Backtesting tip: Use this for strict “what we knew then” alignment. Pair it with /forecast to ensure target and features respect actual publication lags.
10) Provider health: GET /status
Purpose: Monitor last fetch status per data provider. Build alerts and circuit breakers to protect your inference from upstream anomalies.
Practical workflow:
- Before running batch training, call /status; if a provider shows delayed or partial data, gate the job and alert maintainers.
- At runtime, couple /status with retry logic to handle intermittent issues gracefully.
End-to-End Example: Building an XGBoost + SHAP Pipeline with Energy API Time-Series
Below is an illustrative Python workflow that:
- Loads multi-commodity features with /timeseries.
- Aligns to target using /forecast for day-ahead power.
- Trains an XGBoost regressor and computes SHAP values.
- Formats an attribution report that business users can read.
import os
import json
import time
import requests
import pandas as pd
import numpy as np
import xgboost as xgb
import shap
from datetime import datetime
BASE = "https://energy-api.com/api/v1"
API_KEY = os.getenv("ENERGY_API_KEY")
def get_timeseries(start, end, symbols):
params = {
"start": start,
"end": end,
"symbols": ",".join(symbols),
"api_key": API_KEY
}
r = requests.get(f"{BASE}/timeseries", params=params, timeout=30)
r.raise_for_status()
return r.json()
def get_forecast(symbol):
params = {"symbol": symbol, "api_key": API_KEY}
r = requests.get(f"{BASE}/forecast", params=params, timeout=30)
r.raise_for_status()
return r.json()
def retry_get(url, params, retries=3, backoff=1.5):
for i in range(retries):
try:
r = requests.get(url, params=params, timeout=30)
if r.status_code == 200:
return r.json()
# Handle API error schemas
if r.status_code in (422, 404):
return r.json()
except Exception:
pass
time.sleep(backoff ** (i + 1))
raise RuntimeError("Max retries exceeded")
# 1) Define symbols: target (DE day-ahead) + drivers (TTF, EUA, Brent)
target_symbol = "EPEX_DE_DA"
feature_symbols = ["TTF_GAS", "EUA_CO2", "BRENT_CRUDE"]
all_symbols = [target_symbol] + feature_symbols
# 2) Load time-series
data = get_timeseries("2025-01-01", "2025-06-30", all_symbols)
# 3) Convert nested dict to pandas DataFrame
def rates_to_df(rates_dict):
frames = []
for sym, series in rates_dict.items():
s = pd.Series(series, name=sym, dtype=float)
s.index = pd.to_datetime(s.index)
frames.append(s)
return pd.concat(frames, axis=1).sort_index()
df = rates_to_df(data["rates"])
# 4) Feature engineering: pct changes and lags
for sym in feature_symbols:
df[f"{sym}_pct_7d"] = df[sym].pct_change(7)
df[f"{sym}_lag_1"] = df[sym].shift(1)
# 5) Align target: shift target one day ahead for predicting next day
df["TARGET"] = df[target_symbol].shift(-1)
# Drop NaNs from feature creation
df = df.dropna()
X = df.drop(columns=[target_symbol, "TARGET"])
y = df["TARGET"]
# 6) Train XGBoost
dtrain = xgb.DMatrix(X, label=y)
params = {"objective": "reg:squarederror", "max_depth": 5, "eta": 0.05, "subsample": 0.9, "colsample_bytree": 0.8}
model = xgb.train(params, dtrain, num_boost_round=300)
# 7) SHAP explainability
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X)
# 8) Attribution for the last prediction
last_row = X.iloc[[-1]]
last_pred = float(model.predict(xgb.DMatrix(last_row))[0])
last_shap = shap_values[-1]
attribution = sorted(list(zip(last_row.columns, last_shap)), key=lambda x: abs(x[1]), reverse=True)
report = {
"prediction_date": str(X.index[-1].date()),
"predicted_value": round(last_pred, 2),
"top_contributors": [{"feature": f, "shap": round(v, 3)} for f, v in attribution[:8]]
}
print(json.dumps(report, indent=2))
Interpretation:
- The target is tomorrow’s EPEX_DE_DA; features include today’s and lagged drivers (TTF, EUA, Brent) plus a 7-day percent change signal.
- SHAP values decompose the prediction into additive contributions per feature. Surface the top contributors in dashboards and attach them to every trade idea.
- Add intraday curve enrichment by joining /electricity/hourly curves for model calibration and hour-specific models where needed.
Interpreting SHAP Values and Translating to Trading Signals
SHAP decomposes a model’s prediction into additive feature effects around a baseline expectation. For a power price forecast, you can group feature contributions by commodity driver and present explanations in energy-native language. For example:
- Gas complex: Sum contributions from TTF_GAS and its derived features (lags, pct changes).
- Carbon complex: Sum from EUA_CO2 features.
- Macro oil: Sum from BRENT_CRUDE features.
- Electricity carry: Include lagged power, spreads between neighboring zones, or prior intraday shapes from /electricity/hourly where available.
A transparent trading signal can display:
- Point forecast for EPEX_DE_DA[+1] in EUR/MWh.
- Attribution blocks: Gas +€2.30, Carbon +€1.10, Oil -€0.20, Carry +€0.70.
- Confidence context: realized volatility from /ohlc and recent change metrics from /fluctuation.
Tip: Keep a provenance trail. Alongside SHAP outputs, store the exact request parameters and response snippets from Energy API, including symbol currencies and publication dates. This enables perfect reconciliation months later.
Reliability, Governance, and Performance Best Practices
Trading and risk systems deserve production-grade engineering. Here’s how to design for resilience and governance using Energy API patterns.
Routing and retries
- Exponential backoff: For transient 429 or intermittent network hiccups, back off geometrically (e.g., 1.5^n) and cap retries.
- Provider-aware circuit breakers: Use /status to detect upstream provider delays. If a specific provider is lagging, skip new model runs that rely critically on that provider or switch to a fallback feature set.
- Health checks: Ping /status on a schedule and alert when a source transitions from healthy to degraded.
Governance controls
- Per-app keys conceptually map to roles in your internal platform: assign separate credentials per environment or book. Log which application invoked which endpoint and why.
- Audit logs: Persist outbound requests and inbound responses with timestamps. Store the JSON bodies you used to compute SHAP so investigators can reproduce results.
- Data locality: Tag stored data by region and source. If you operate in multiple jurisdictions, maintain clear lineage from each endpoint call to your forecast artifacts.
Observability
- Structured logging: Record endpoint path, symbol list, response success flag, and request latency in each call. Emit counters by category (electricity, gas, oil, coal, carbon, carbon intensity).
- SLIs and SLOs: Track ingestion latency, completeness (expected series vs actual), and attribution coverage (% of forecasts with SHAP attached).
- Testing: Unit test symbol lists with /symbols; integration test timeseries alignment and curve sizes for /electricity/hourly.
Performance
- Batch queries: Prefer multi-symbol calls to /timeseries and /latest to minimize overhead and ensure consistent fetch points.
- Caching: Cache symbol metadata and slow-moving macro series (like monthly OHLC) to reduce downstream latency.
- Regional routing: If your systems are multi-region, co-locate your feature preparation jobs near the application servers that consume them to reduce end-to-end latency.
Error handling
- 401/422/404: Parse the standardized error message and log details. 422 usually indicates a validation error (e.g., missing symbol). 404 indicates no data for the selection.
- 429: Implement exponential backoff and jitter; reschedule batch jobs if necessary.
- Parsing safety: Always check success before dereferencing fields. Keep robust defaults when a symbol lacks a value on a given date.
Working with Multiple Commodities in One Call
One of the biggest accelerators for explainability is that Energy API lets you query heterogeneous markets in a single request. For example, suppose you need today’s German day-ahead auction, TTF gas, and EU ETS to update a fast intraday monitor:
curl -G https://energy-api.com/api/v1/latest \
--data-urlencode "symbols=EPEX_DE_DA,TTF_GAS,EUA_CO2" \
--data-urlencode "api_key=YOUR_API_KEY"
You get synchronized timestamps and currency metadata and can instantly diff them to yesterday’s /historical snapshot. This makes it trivial to show “what moved today” and to justify why your signal ticked up or down before the next day-ahead publication.
JavaScript Example: Front-End Dashboard for Transparent Signals
Here’s a minimal front-end snippet that fetches multi-commodity latest values and renders a SHAP-style narrative for a forecast that your back-end provides. In practice, you’d proxy calls through your server.
<script>
async function fetchLatest(symbols) {
const params = new URLSearchParams({
symbols: symbols.join(","),
api_key: "YOUR_API_KEY"
});
const url = `https://energy-api.com/api/v1/latest?${params.toString()}`;
const r = await fetch(url);
const j = await r.json();
return j;
}
(async () => {
const j = await fetchLatest(["EPEX_DE_DA","TTF_GAS","EUA_CO2"]);
if (j.success) {
const { rates, dates, currencies } = j;
console.log("Latest snapshot:", rates, dates, currencies);
// Render your attribution summary fetched from your internal model service
// Example narrative (static for demo):
const narrative = [
"Gas added +€2.1/MWh (TTF rose today).",
"Carbon added +€0.9/MWh (EUA up 1.2%).",
"Oil neutral (-€0.1/MWh)."
];
document.getElementById("narrative").innerText = narrative.join(" ");
}
})();
</script>
This pattern keeps Energy API for authoritative market data and your own service for model outputs and SHAP attributions — the clean separation you want in production.
Detailed Endpoint Coverage and Business Value
Energy API endpoints and their purpose:
- /symbols: Discover instruments and metadata. Value: dynamic feature registry, validation of expected fields.
- /latest: Last-published values for mixed commodities. Value: intraday monitors and quick narrative updates.
- /historical: Point-in-time backtested snapshots. Value: reproducible research and auditing.
- /timeseries: Multi-commodity historical series. Value: training/validation data and analytics.
- /fluctuation: Start/end and percentage change across periods. Value: simple, powerful feature engineering.
- /ohlc: Weekly/monthly/quarterly candles. Value: volatility and persistence features.
- /electricity/latest: Quick scan of electricity symbols. Value: monitors and alerts.
- /electricity/hourly: Intraday curves. Value: hour-level modeling and post-trade attribution.
- /electricity/pvpc: Spanish PVPC hourly reference. Value: consumer-side proxy or validation target.
- /gas/latest: TTF and Henry Hub in one call. Value: fast macro driver inputs.
- /emissions/latest: EUA_CO2. Value: carbon cost driver for EU power.
- /coal/latest: API2 and Newcastle. Value: fuel stack context for coal-sensitive markets.
- /carbon-intensity: Grid gCO2eq/kWh. Value: ESG overlays and eco-impact analytics.
- /forecast: Next published day-ahead price (deterministic). Value: target alignment and operational triggers.
- /cost-estimate: Simple cost calculator (latest price × kWh/month). Value: consumer-facing estimators and budgeting tools.
- /status: Provider health. Value: reliability, gating, and observability.
Each endpoint contributes to a transparent ML stack: from clean discovery (/symbols) through robust feature assembly (/timeseries, /electricity/hourly) to deterministic targets (/forecast) and healthy operations (/status). The consistent JSON schema across all commodities is the multiplier.
Real-World Use Cases
1) Price Alert and Attribution Feed
Build a microservice that polls /latest for EPEX_DE_DA, TTF_GAS, and EUA_CO2. When thresholds are crossed, your back-end generates a quick one-line explanation — “Gas +2.3% today; model sensitivity implies +€1.1/MWh to tomorrow’s DE DA” — using precomputed SHAP sensitivities. Endpoints used: /latest, optionally /fluctuation for context, and your own model service for SHAP.
2) ESG Dashboard with Carbon-Adjusted Power Cost
Combine /electricity/pvpc with /emissions/latest and /carbon-intensity for ES to show a consumer-facing dashboard: “Today’s PVPC is €X; grid intensity is Y gCO2eq/kWh; EUA is Z €/tCO2.” Explain cost and eco-intensity trends with descriptive narratives. Endpoints used: /electricity/pvpc, /carbon-intensity, /emissions/latest.
3) Trading P&L View with Explainable Drivers
A risk dashboard that merges realized DA prices with your model’s SHAP attributions, flagged by macro regime. Pull daily ground truth via /forecast and historicals via /timeseries; overlay /ohlc volatility to shade P&L charts during high-vol periods. Endpoints used: /forecast, /timeseries, /ohlc.
Complete JSON Example: Carbon Intensity Snapshot
Pulling carbon intensity supports sustainability overlays and eco-cost analytics next to price forecasts.
curl -G "https://energy-api.com/api/v1/carbon-intensity" \
--data-urlencode "country=DE" \
--data-urlencode "api_key=YOUR_API_KEY"
{
"success": true,
"country": "DE",
"unit": "gCO2eq/kWh",
"series": [
{"timestamp": "2025-09-15T00:00:00+02:00", "value": 408},
{"timestamp": "2025-09-15T01:00:00+02:00", "value": 401}
// ...
],
"source": "Official grid data via Energy API"
}
Use this to qualify “green hours” in post-trade reporting, or to explain why high wind output coincided with lower carbon intensity and moderated prices — valuable context next to SHAP attributions.
Another End-to-End Flow: Cost Estimation Meets Explainability
For energy retail or SMB tools, a simple cost estimator plus explainability can demystify monthly bills. While your forecast model handles the price outlook, the cost estimator endpoint provides a quick translation.
curl -X POST https://energy-api.com/api/v1/cost-estimate \
-H "Content-Type: application/json" \
-d '{
"symbol": "OMIE_ES_DA",
"kwh_per_month": 1200,
"api_key": "YOUR_API_KEY"
}'
Illustrative JSON:
{
"success": true,
"symbol": "OMIE_ES_DA",
"kwh_per_month": 1200,
"currency": "EUR",
"latest_price": 72.5,
"estimated_cost": 87.0,
"note": "Wholesale-only estimate; excludes taxes and network charges."
}
You can couple this output with a lightweight attribution summary such as, “Gas added +€4 this month; Carbon +€2; Oil -€1,” based on your SHAP decomposition of the latest price drivers, creating a highly transparent customer experience.
FAQ
How often does the TTF gas price update?
TTF_GAS follows its source publication schedule and is normalized by Energy API into the shared schema. Use /latest for the most recent value and /timeseries for historicals; consult the dates field per symbol to align features precisely in your model and backtests.
Can I get historical energy prices going back 5 years?
Historical coverage depends on the underlying source, and Energy API exposes it through /timeseries with the same JSON structure across commodities. You can request broad ranges and programmatically inspect returned dates per symbol for completeness.
Does the API support multiple currencies in one call?
Yes. When you query mixed commodities in a single request (e.g., BRENT_CRUDE in USD and TTF_GAS in EUR), the response indicates base as MIXED and includes per-symbol currencies. This is ideal for modeling in native terms and normalizing later at the P&L stage.
How do I handle non-publishing days and holidays in backtests?
Use /historical with an as-of date. If the date falls on a non-publishing day, Energy API returns the most recent available value before it. This rule lets you build reproducible backtests and align targets with /forecast.
What if a data provider has a temporary outage?
Call /status to check provider health and gate ingestion or inference runs accordingly. Combine this with exponential backoff on transient errors and circuit breakers around feature sets that rely on the affected provider.
Conclusion + CTA
Explainable ML for power trading hinges on three pillars: trustworthy data, reproducible targets, and clear attributions. With a single normalized interface across electricity, gas, oil, coal, and carbon, Energy API eliminates the ETL grind and gives you deterministic endpoints for both features and targets — including intraday curves and day-ahead auction results. The result is an explainability stack that traders can trust and compliance can audit.
In practice, you will assemble multi-commodity features with /timeseries, calibrate with /electricity/hourly, align targets via /forecast, and quantify context with /fluctuation and /ohlc. Your SHAP layer then translates predictions into concrete, commodity-level narratives: “Gas +€2.1; Carbon +€0.9; Oil -€0.1,” attached to every forecast. Add health monitoring with /status and you have a production-ready system.
Build transparent energy analytics faster with the platform designed for developers. Explore the endpoints, wire your pipeline, and ship a clean, explainable forecasting product in days, not weeks. Visit Energy API and Try Energy API for free to start integrating explainable energy data into your trading stack today.
Ready to get started?
Get your API key and start querying energy commodity prices in minutes.
Get API KeyRelated posts
Discover how integrating Distributed Ledger Technology with Energy API can revolutionize transparent energy tr...
Read more →
Discover how Energy API and blockchain technology are revolutionizing secure and transparent energy transactio...
Read more →
Discover how to create a fair and transparent energy marketplace using Energy API for accurate pricing and eff...
Read more →
Discover how Energy API transforms energy trading strategies with machine learning. Streamline data access and...
Read more →
Unlock insights in the energy market with our guide on using Energy API and machine learning. Streamline data...
Read more →