Real-Time Basis Arbitrage Across Hubs: Detecting and Executing Spread Opportunities with Energy API Market Feeds
Energy markets don’t pause so your ETL can catch up. When a locational spread opens between hubs — TTF gas versus Henry Hub, OMIE Spain day‑ahead versus EPEX Germany, Brent versus WTI, or even EUA carbon allowances versus power prices — you need to detect it in minutes, measure basis risk, and execute (or simulate) the hedge while liquidity exists. But the raw inputs you need are locked behind different official sources, different time zones, incompatible date formats, and publishing schedules that drift by the day. Building and maintaining a set of fragile scrapers and one‑off normalizers is the opposite of “edge”; it’s background toil that steals velocity from your trading stack and forecast models.
This post shows how to solve that with a single, normalized data plane. We’ll design an end‑to‑end approach for real‑time basis arbitrage across hubs using energy-api.com: a unified, REST-based interface that aggregates wholesale electricity, natural gas, crude oil, coal, carbon allowances, and grid carbon intensity data from official sources and returns everything in a consistent JSON schema. We’ll wire up a minimal spread engine that scans for cross‑hub opportunities, calculates basis deltas and vol‑adjusted thresholds, and reacts using deterministic day‑ahead results and intraday electricity curves where available. You’ll leave with practical code you can drop into a backend worker, quant notebook, or a lightweight service powering alerts and dashboards.
Throughout, we’ll emphasize developer ergonomics: a single symbols registry; consistent currency metadata; intraday and daily series in the same wire format; and endpoints designed to cover both exploratory analytics and production monitoring. If your mandate is to ship a robust basis-detection service this week, not next quarter, this is for you.
Introduction
Basis arbitrage depends on two things: fast, clean data and reliable cross‑hub comparability. Detecting a profitable spread between OMIE Spain day‑ahead power (OMIE_ES_DA) and EPEX Germany day‑ahead (EPEX_DE_DA) is straightforward in theory — subtract two time‑aligned prices in the same currency and you have a basis number. In practice, developers wrestle with inconsistent publication schedules, mismatched currencies, evolving symbol taxonomies, and missing hours. Gas and power are also published on different cadences — daily for hubs like TTF and hourly/quarter‑hourly intraday for many power markets — complicating cross‑commodity hedges (e.g., power vs. gas spark‑spread adjustments).
The business pain is acute: if your data plane drops, a spread can widen and revert before your job restarts. If your code normalizes one provider’s symbol list and another provider changes a filename schema, your “simple” P&L attribution job starts returning nulls. Traders, risk teams, and ESG stakeholders all need dependable, auditable inputs. You need a single place to query, a single schema to parse, and built‑in hints about currency, frequency, and source health.
This is exactly what Energy API provides. You can query multiple commodities (gas, electricity, carbon, oil, coal, carbon intensity) in one call; you can ask for intraday electricity curves; and you can fetch official day‑ahead auction results deterministically without building a web‑scraping apparatus. In the rest of this post, we’ll design a reference basis‑arbitrage workflow on top of the endpoints most relevant to cross‑hub and cross‑commodity spreads.
Why Energy API
Here are the differentiators that matter when you’re moving from prototype to production:
- One normalized surface replaces five+ official sources. You no longer need separate connectors for OMIE, ENTSO‑E, ESIOS, and EIA/FRED. Every query returns the same JSON shape with currency and frequency metadata available at a glance. This reduces your parsing code paths and the test surface you must maintain.
- Cross‑commodity, multi‑symbol queries in a single call. You can pull TTF_GAS, BRENT_CRUDE, EUA_CO2, and OMIE_ES_DA in one request and receive a schema‑consistent payload keyed by symbol. Basis detection often spans commodities (e.g., power vs. gas, power vs. EUA), so this saves you multiple network round trips and eliminates stitching logic.
- Intraday electricity curves where sources publish them. For real‑time spread detection and re‑hedging (e.g., sub‑hourly deviations vs. day‑ahead), the /electricity/hourly endpoint provides the full curve on a given date, using 15‑minute or hourly granularity. This is essential for intra‑day convergence strategies and profile‑specific hedging.
- Developer‑first primitives for monitoring and recovery. The /status endpoint summarizes provider health to help you decide whether to fail open (fallback) or fail closed. Combined with deterministic /forecast of auctioned day‑ahead prices (not a predictive model), you can set up circuit breakers and cache policies that keep your systems stable when sources delay publication.
The net result: fewer vendor‑specific branches in your code, faster time to insight, and easier auditability. For engineering leaders and data platform owners, this means less ETL debt, fewer operational incidents, and cleaner interfaces for consuming teams (quant, trading, ESG analytics, and finance).
Quick Start
Base URL:
https://energy-api.com/api/v1
Requests include an api_key query parameter. For example, let’s detect a simple cross‑commodity snapshot: Brent vs. TTF gas vs. EU carbon allowances — three different providers and currency regimes returned together.
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"
Sample 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"
}
}
Key fields:
- success: Boolean indicator that your call resolved with valid data.
- date: Canonical date for the snapshot; individual symbols have their own dates in dates to reflect publication calendars.
- rates: Latest price per symbol.
- currencies: Currency for each symbol, used to align spreads if you’re comparing cross‑currency hubs.
For basis strategies, you’ll typically convert to a common currency (e.g., EUR) and then compute spreads or ratios. Because the schema is shared across endpoints, you can reuse the same post‑processing for /latest or /historical series.
Core Endpoints For Basis Arbitrage
Let’s walk the endpoints you’ll lean on to detect, validate, and monitor cross‑hub spreads. We’ll include request examples, responses, and how to interpret each payload in a trading or analytics loop.
1) Discover tradable symbols with /symbols
The /symbols endpoint returns the authoritative registry of active symbols, including name, category, country, frequency, and currency. Use this to populate dropdowns, validate user input, and drive dynamic scans (e.g., “all electricity hubs in EU”).
Endpoint:
GET /api/v1/symbols
Important params:
- category: gas | electricity | oil | coal | carbon | carbon_intensity
- base: Optional currency filter.
- provider: Optional filter by upstream provider.
Example: list gas symbols.
curl -G https://energy-api.com/api/v1/symbols \
--data-urlencode "category=gas" \
--data-urlencode "api_key=YOUR_API_KEY"
Sample response (truncated):
{
"success": true,
"count": 2,
"symbols": [
{
"symbol": "TTF_GAS",
"name": "TTF Natural Gas Day-Ahead",
"category": "gas",
"country_code": "EU",
"currency_code": "EUR",
"frequency": "daily",
"description": "TTF day-ahead price published by EEX."
},
{
"symbol": "HENRY_HUB",
"name": "Henry Hub Natural Gas",
"category": "gas",
"country_code": "US",
"currency_code": "USD",
"frequency": "daily",
"description": "Henry Hub spot price published by EIA."
}
]
}
Field meanings:
- symbol: The exact identifier used in all other endpoints.
- currency_code and frequency: Critical for basis comparisons and time alignment.
- description: Helpful for tooltips or audit metadata in a UI.
Best practice: Cache this list once per day. In validation layers, reject unknown symbols to avoid 404s and improve UX.
2) Snapshots with /latest
For real‑time spread detection, you’ll poll /latest to get the newest values across multiple hubs or commodities in one go. It’s common to combine gas, electricity, and carbon prices here to monitor composite strategies such as spark or dark spreads with carbon costs.
Endpoint:
GET /api/v1/latest
Params:
- symbols: Comma‑separated list (e.g., OMIE_ES_DA,EPEX_DE_DA,TTF_GAS,EUA_CO2).
- category or base: Optional filters.
Example: Power hub spread snapshot.
curl -G https://energy-api.com/api/v1/latest \
--data-urlencode "symbols=OMIE_ES_DA,EPEX_DE_DA,EUA_CO2,TTF_GAS" \
--data-urlencode "api_key=YOUR_API_KEY"
Interpretation:
- Use currencies to normalize to a single base (e.g., EUR).
- Subtract OMIE_ES_DA − EPEX_DE_DA for the raw hub basis.
- Optionally adjust for EUA_CO2 and TTF_GAS to evaluate implied spark or clean spreads.
3) History and backtests with /timeseries
To avoid false positives, spread strategies need context: how unusual is the current basis versus the last 30/90/365 days? The /timeseries endpoint returns per‑symbol series keyed by date, perfect for rolling z‑scores, seasonal analysis, and model training.
Endpoint:
GET /api/v1/timeseries
Params:
- start, end: YYYY‑MM‑DD.
- symbols: One or more.
- base: Optional currency filter.
Example:
curl -G https://energy-api.com/api/v1/timeseries \
--data-urlencode "start=2025-01-01" \
--data-urlencode "end=2025-03-31" \
--data-urlencode "symbols=OMIE_ES_DA,EPEX_DE_DA" \
--data-urlencode "api_key=YOUR_API_KEY"
Sample response:
{
"success": true,
"base": "MIXED",
"start_date": "2025-01-01",
"end_date": "2025-03-31",
"rates": {
"OMIE_ES_DA": {
"2025-01-01": 62.10,
"2025-01-02": 58.45
},
"EPEX_DE_DA": {
"2025-01-01": 55.00,
"2025-01-02": 53.80
}
},
"frequencies": {
"OMIE_ES_DA": "daily",
"EPEX_DE_DA": "daily"
},
"currencies": {
"OMIE_ES_DA": "EUR",
"EPEX_DE_DA": "EUR"
}
}
Field meanings and usage:
- rates: Per‑symbol date map. Compute daily basis = OMIE_ES_DA[d] − EPEX_DE_DA[d].
- frequencies: Confirms whether daily vs. hourly. The shown example is daily.
- Use the series to run a rolling mean and standard deviation for a z‑score threshold (e.g., enter at |z| ≥ 2, exit at mean reversion).
4) Intraday convergence with /electricity/hourly
If your strategy refines entries after day‑ahead publication — or you manage intra‑day hedges — the full intraday curve is crucial. /electricity/hourly returns hourly or 15‑min prices (depending on source) for a given symbol and date, enabling fine‑grained basis measurement and profile‑shaped hedges.
Endpoint:
GET /api/v1/electricity/hourly
Params:
- symbol: e.g., OMIE_ES_DA.
- date: YYYY‑MM‑DD (market day).
Example:
curl -G "https://energy-api.com/api/v1/electricity/hourly" \
--data-urlencode "symbol=OMIE_ES_DA" \
--data-urlencode "date=2026-06-11" \
--data-urlencode "api_key=YOUR_API_KEY"
Sample response (excerpt):
{
"success": true,
"symbol": "OMIE_ES_DA",
"date": "2026-06-11",
"granularity": "hourly",
"currency": "EUR",
"curve": [
{"time": "2026-06-11T00:00:00+01:00", "price": 58.10},
{"time": "2026-06-11T01:00:00+01:00", "price": 56.50},
{"time": "2026-06-11T02:00:00+01:00", "price": 54.80}
]
}
Interpretation:
- curve: Array of time‑stamped points in local market time. Align curves across two hubs to compute an hourly basis vector.
- granularity: “hourly” or “15min” depending on the provider’s intraday resolution.
- Use this data to detect intra‑day divergence/convergence beyond day‑ahead expectations and to calculate profile‑weighted spreads for a given consumption shape.
5) Day‑ahead auction results with /forecast
For auction‑sourced electricity symbols, /forecast returns the next published day‑ahead schedule deterministically. This is not a model — it’s a safe way to consume official day‑ahead results as soon as they’re published, which fits directly into your pre‑open spread checks.
Endpoint:
GET /api/v1/forecast
Params:
- symbol: An auction‑sourced electricity symbol such as OMIE_ES_DA or EPEX_DE_DA.
Example:
curl -G "https://energy-api.com/api/v1/forecast" \
--data-urlencode "symbol=EPEX_DE_DA" \
--data-urlencode "api_key=YOUR_API_KEY"
Practical tip: Use this to schedule your pre‑market spread engine, fetch both hubs’ day‑ahead, normalize to EUR, and set entry conditions before liquidity peaks.
6) Gas and carbon pivots with /gas/latest and /emissions/latest
For clean spark or cross‑commodity basis overlays, pair electricity spreads with TTF_GAS (EU) and EUA_CO2. Two convenient category endpoints combine key symbols in one call.
Endpoints:
GET /api/v1/gas/latest
GET /api/v1/emissions/latest
Example:
curl -G https://energy-api.com/api/v1/gas/latest \
--data-urlencode "api_key=YOUR_API_KEY"
curl -G https://energy-api.com/api/v1/emissions/latest \
--data-urlencode "api_key=YOUR_API_KEY"
Usage: Merge these snapshots with your power hub prices to build clean‑spark spread curves with carbon costs, or to sanity‑check cross‑commodity signals (e.g., if gas moved 10% intraday but the power spread didn’t budge, re‑evaluate the entry).
7) Trend strength with /fluctuation and structure with /ohlc
Two analysis helpers support risk‑based entry thresholds and regime detection:
- /fluctuation returns start/end values and percentage change for a period. Use it to compute spread momentum or confirm that a hub’s weekly move is within your risk budget.
- /ohlc builds weekly/monthly/quarterly candles for volatility analysis. For spreads, you can transform two OHLC streams into a synthetic OHLC for the basis (open_to_open deltas, etc.) and rank opportunities by recent volatility.
Example: /fluctuation for OMIE_ES_DA and EPEX_DE_DA.
curl -G https://energy-api.com/api/v1/fluctuation \
--data-urlencode "start=2026-05-01" \
--data-urlencode "end=2026-06-11" \
--data-urlencode "symbols=OMIE_ES_DA,EPEX_DE_DA" \
--data-urlencode "api_key=YOUR_API_KEY"
Example: /ohlc monthly candles for TTF_GAS and BRENT_CRUDE.
curl -G https://energy-api.com/api/v1/ohlc \
--data-urlencode "symbols=TTF_GAS,BRENT_CRUDE" \
--data-urlencode "period=monthly" \
--data-urlencode "start=2025-01-01" \
--data-urlencode "end=2026-06-30" \
--data-urlencode "api_key=YOUR_API_KEY"
Use candles to derive a volatility score for risk‑parity allocation across multiple spreads (e.g., power‑power vs. gas‑power vs. oil‑gas).
8) Provider health with /status
If a source is temporarily delayed, robust systems avoid false negatives by failing open with cached prices or failing closed with a paused strategy. The /status endpoint gives you a heartbeat per upstream provider. Use it to inform retries and circuit‑breaker logic.
Endpoint:
GET /api/v1/status
Example:
curl -G https://energy-api.com/api/v1/status \
--data-urlencode "api_key=YOUR_API_KEY"
Recommended pattern: If status indicates a delay for an auction source, treat spreads as stale and avoid new entries until publication normalizes.
From Data To Decisions: A Reference Basis Engine
Let’s stitch these endpoints into an actionable loop that (1) screens spreads, (2) confirms conditions with historical context, and (3) refines with intraday signals.
Step 1: Universe and symbol hygiene
Query /symbols and keep a curated list of eligible hubs and commodities, tagged with:
- Currency: to normalize into a working base (e.g., EUR for EU‑centric books).
- Frequency: daily vs. intraday to define alignment logic.
- Region: for clustering (Iberia vs. DACH vs. pan‑EU).
Store this map in a small key‑value store and refresh daily.
Step 2: Real‑time screening
Pull /latest for your primary pairs (e.g., OMIE_ES_DA and EPEX_DE_DA). Convert currencies as needed. Compute spread = HubA − HubB. If absolute spread exceeds a rolling threshold derived from /timeseries (e.g., 90‑day mean ± 2σ), flag for action.
Grab /gas/latest and /emissions/latest to estimate clean‑spark adjustments where relevant. For example, if EU gas rallied sharply but the power‑power spread didn’t move, you may adjust expected convergence speed or entry level.
Step 3: Historical context and regime checks
Use /timeseries for the last 1–2 years on both hubs. Compute:
- Rolling mean and standard deviation of the spread.
- Seasonality: median spread by month or weekday.
- Regime filters: Compare current month’s OHLC candle metrics from /ohlc to the prior quarter to detect volatility shifts.
When spreads breach your volatility‑adjusted guardrails, create a ticket or auto‑enter your execution leg in a simulated stack.
Step 4: Intraday refinement
Fetch /electricity/hourly for each hub on market day D. Compute an hourly basis curve and weight by your expected load shape or by standardized profiles (e.g., peak/off‑peak). If the day‑ahead indicated a trade, but the early intraday curve shows rapid convergence, downsize or delay entries.
Step 5: Health‑aware robustness
Ping /status at the start of your job. If a key provider is delayed, switch to a cached price and mark spreads as provisional. Use exponential back‑off on retries and write a note in your audit log. When publication completes, reconcile any provisional decisions.
Complete, Realistic Examples
Let’s put the pieces together with code and full JSON, so you can lift these into a worker or notebook. We’ll implement a minimal basis scan between OMIE_ES_DA and EPEX_DE_DA, sanity‑check with gas and carbon, and compute a simple z‑score.
cURL: Multi‑symbol snapshot and historical pull
# 1) Latest snapshot across four symbols
curl -G https://energy-api.com/api/v1/latest \
--data-urlencode "symbols=OMIE_ES_DA,EPEX_DE_DA,TTF_GAS,EUA_CO2" \
--data-urlencode "api_key=YOUR_API_KEY"
# 2) Historical series for the hubs
curl -G https://energy-api.com/api/v1/timeseries \
--data-urlencode "start=2025-06-01" \
--data-urlencode "end=2026-06-11" \
--data-urlencode "symbols=OMIE_ES_DA,EPEX_DE_DA" \
--data-urlencode "api_key=YOUR_API_KEY"
# 3) Intraday curve for current market day
curl -G "https://energy-api.com/api/v1/electricity/hourly" \
--data-urlencode "symbol=OMIE_ES_DA" \
--data-urlencode "date=2026-06-11" \
--data-urlencode "api_key=YOUR_API_KEY"
JavaScript (Node): Compute a z‑score and trigger an alert
import fetch from "node-fetch";
const BASE = "https://energy-api.com/api/v1";
const API_KEY = process.env.ENERGY_API_KEY;
async function latest(symbols) {
const url = new URL(BASE + "/latest");
url.searchParams.set("symbols", symbols.join(","));
url.searchParams.set("api_key", API_KEY);
const res = await fetch(url.toString());
if (!res.ok) throw new Error("latest failed: " + res.status);
return res.json();
}
async function timeseries(symbols, start, end) {
const url = new URL(BASE + "/timeseries");
url.searchParams.set("symbols", symbols.join(","));
url.searchParams.set("start", start);
url.searchParams.set("end", end);
url.searchParams.set("api_key", API_KEY);
const res = await fetch(url.toString());
if (!res.ok) throw new Error("timeseries failed: " + res.status);
return res.json();
}
function mean(arr) { return arr.reduce((a, b) => a + b, 0) / arr.length; }
function std(arr) {
const m = mean(arr);
return Math.sqrt(mean(arr.map(x => (x - m) ** 2)));
}
(async () => {
const hubs = ["OMIE_ES_DA", "EPEX_DE_DA"];
const snap = await latest([...hubs, "TTF_GAS", "EUA_CO2"]);
const omie = snap.rates["OMIE_ES_DA"];
const epex = snap.rates["EPEX_DE_DA"];
const spreadNow = omie - epex;
const hist = await timeseries(hubs, "2025-06-01", "2026-06-11");
const omieSeries = hist.rates["OMIE_ES_DA"];
const epexSeries = hist.rates["EPEX_DE_DA"];
const commonDates = Object.keys(omieSeries).filter(d => epexSeries[d] != null);
const spreadHist = commonDates.map(d => omieSeries[d] - epexSeries[d]);
const mu = mean(spreadHist);
const sigma = std(spreadHist);
const z = (spreadNow - mu) / (sigma || 1);
if (Math.abs(z) >= 2) {
console.log("ALERT: Hub spread z-score", z.toFixed(2), "Spread:", spreadNow.toFixed(2), "EUR/MWh");
} else {
console.log("No signal. z:", z.toFixed(2));
}
})();
Python: Build an hourly basis curve and compute a profile‑weighted spread
import os, requests, datetime as dt
BASE = "https://energy-api.com/api/v1"
API_KEY = os.environ["ENERGY_API_KEY"]
def get_hourly(symbol, date):
r = requests.get(f"{BASE}/electricity/hourly", params={"symbol": symbol, "date": date, "api_key": API_KEY})
r.raise_for_status()
return r.json()
def profile_weighted_spread(curve_a, curve_b, weights):
# weights is a dict keyed by hour index (0..23) => weight sum to 1
# curves are arrays of {time, price} hourly entries
# align by index for simplicity (production: align by timestamp)
spread = 0.0
hours = min(len(curve_a), len(curve_b), 24)
for i in range(hours):
spread += (curve_a[i]["price"] - curve_b[i]["price"]) * weights.get(i, 0.0)
return spread
date = dt.date.today().isoformat()
omie = get_hourly("OMIE_ES_DA", date)
epex = get_hourly("EPEX_DE_DA", date)
# Simple peak hours weight: hours 8-20 equal weights, else zero
w = {h: (1/13) for h in range(8, 21)}
pw_spread = profile_weighted_spread(omie["curve"], epex["curve"], w)
print("Peak-weighted spread:", round(pw_spread, 2), omie["currency"])
Full JSON: /fluctuation example and field walkthrough
{
"success": true,
"start": "2026-05-01",
"end": "2026-06-11",
"results": {
"OMIE_ES_DA": {
"start_value": 61.80,
"end_value": 58.90,
"change": -2.90,
"change_pct": -4.69
},
"EPEX_DE_DA": {
"start_value": 56.40,
"end_value": 54.30,
"change": -2.10,
"change_pct": -3.72
}
}
}
Interpretation:
- Use change_pct to rank markets by recent drift; you might demand larger z‑scores during high‑drift periods.
- Combine with your z‑score to prevent stacking similar bets across multiple hubs (risk concentration).
Error Handling, Retries, And Data Hygiene
Production basis engines need good manners. Here’s how to keep your system healthy and auditable:
- HTTP 401: Missing/invalid credentials. Treat as configuration error; do not retry blindly.
- HTTP 404: No data for symbol or date. For auction days, check /status to see if the provider is delayed. Fall back to the most recent valid date via /historical if your workflow allows.
- HTTP 422: Validation error. Validate symbols up front using /symbols and check parameter formats before sending requests.
- HTTP 429: Rate‑limit exceeded. Implement exponential back‑off with jitter and degrade gracefully by widening your polling interval or relying on cached responses when feasible.
Error shape:
{
"success": false,
"error": "Human-readable message."
}
Operational tips:
- Use /status for provider health. If a provider’s last fetch is delayed, avoid executing new entries and mark data as provisional.
- Normalize currencies immediately after a response. Keep a currency map from currencies in the payload (e.g., USD for BRENT_CRUDE, EUR for OMIE_ES_DA).
- Time alignment: For intraday, align by timestamp, not by array index. Electricity curves are in local market time; convert to a canonical timezone for cross‑hub comparison.
- Cache: Memoize /symbols and stable historical windows. Reuse results across jobs to reduce latency.
Real‑World Use Cases
1) Real‑time hub spread alerting for power desks
A backend worker polls /latest for OMIE_ES_DA and EPEX_DE_DA, computes a z‑score using /timeseries, and posts to Slack when |z| ≥ 2. The worker refines the entry with /electricity/hourly to check early intraday convergence. Endpoints: /latest, /timeseries, /electricity/hourly, /status.
2) Clean spark spread monitor with carbon overlay
A dashboard pulls /electricity/latest for EU hubs, /gas/latest for TTF_GAS, and /emissions/latest for EUA_CO2. It computes an indicative clean spark spread (CSS) with a configurable heat rate and carbon factor per plant. It uses /fluctuation to show month‑to‑date change percentages and /ohlc for a volatility panel. Endpoints: /electricity/latest, /gas/latest, /emissions/latest, /fluctuation, /ohlc.
3) Basis backtesting and P&L attribution
A research notebook fetches /timeseries for two hubs over five years, computes synthetic spread series, and then simulates an entry/exit strategy based on z‑scores and OHLC‑derived volatility regimes. A separate P&L attribution script attributes slippage to intraday curve deviations using /electricity/hourly. Endpoints: /timeseries, /ohlc, /electricity/hourly.
Additional Endpoints You’ll Use Along The Way
While the above cover the core, a few more endpoints round out a production system:
- /historical: Point‑in‑time lookups for reconciliation; if a date is a non‑publishing day, the latest prior value is returned. This helps produce consistent T+1 reports even across weekends or holidays.
- /electricity/latest: Quickly list all electricity hubs’ latest values, optionally filtered by country (e.g., DE, ES). Ideal for overview screens and anomaly detection.
- /coal/latest: Fetch COAL_ROTTERDAM (API2) and COAL_NEWCASTLE for dark spread overlays or fuel switching analysis.
- /carbon-intensity: Pull CARBON_INT_DE or CARBON_INT_EU to annotate spreads with grid intensity context for ESG reporting and policy‑driven constraints.
- /cost-estimate (POST): For retail‑oriented apps tied to wholesale trends, multiply latest price by monthly kWh to produce a rough cost estimate (ex‑taxes/network). Not directly a trading feature, but useful in multi‑product platforms bridging wholesale and retail narratives.
Sample: /historical and /electricity/latest responses
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"
{
"success": true,
"date": "2025-09-15",
"base": "MIXED",
"rates": {
"BRENT_CRUDE": 71.45,
"TTF_GAS": 36.20
},
"currencies": {
"BRENT_CRUDE": "USD",
"TTF_GAS": "EUR"
}
}
curl -G https://energy-api.com/api/v1/electricity/latest \
--data-urlencode "country=DE" \
--data-urlencode "api_key=YOUR_API_KEY"
Use /electricity/latest to display German hubs in a single panel, enriching each with volatility or spread to neighboring markets.
Performance Tips And Best Practices
- Batch symbols: Prefer one /latest call for many symbols over N calls for single symbols to reduce latency and variance.
- Warm caches: Preload /timeseries windows you know you’ll need for z‑score calculations at the market open.
- Locality and timezones: Convert intraday curve timestamps to a canonical timezone before joining across countries. Persist the original local timestamps for auditability.
- Resilience: Wrap calls with retries and jitter, and check /status first to avoid hammering a source during known delays.
- Unit conversion: Standardize units (EUR/MWh vs. USD/barrel vs. USD/MMBtu). For cross‑commodity overlays, implement a conversion layer and document assumptions (e.g., heat rates, emissions factors).
FAQ
How often does the TTF gas price update?
TTF_GAS is provided as a daily series reflecting the most recent published value from official sources. Use /gas/latest for a snapshot and /timeseries for historical context. If you’re scanning power‑gas overlays, combine it with electricity hubs from /electricity/latest or /electricity/hourly.
Can I get historical energy prices going back multiple years?
Yes. Use /timeseries with start and end dates to retrieve multi‑year ranges for supported symbols across electricity, gas, oil, coal, carbon, and carbon intensity. For reconciliation of specific past days (including non‑publishing days), use /historical.
Does the API support multiple commodities in one request?
Yes. You can query mixed categories together with /latest or /timeseries by passing multiple symbols (e.g., OMIE_ES_DA,EPEX_DE_DA,TTF_GAS,EUA_CO2). The response includes per‑symbol currency metadata so you can normalize before computing spreads.
What’s the difference between /forecast and /electricity/hourly?
/forecast returns the next published day‑ahead schedule for auction‑based symbols — a deterministic, official result. /electricity/hourly returns the intraday curve for a given market day at hourly or 15‑minute resolution, which you use for intra‑day convergence and profile‑weighted hedging.
How do I monitor data availability to avoid false alarms?
Query /status to check the last fetch per provider. If there’s a publication delay, pause new signals, extend cache TTLs, or flag spreads as provisional. Combine health checks with idempotent retries and back‑off for robust operations.
Conclusion + CTA
Real‑time basis arbitrage across hubs isn’t won with the fanciest model; it’s won with dependable, normalized data and clean engineering. By unifying electricity, gas, oil, coal, carbon, and carbon intensity into a single JSON surface, energy-api.com strips away the ETL and source idiosyncrasies so you can focus on execution, risk, and insight. Whether you’re building a desk‑side alerting agent, an intraday hedging tool, or a research pipeline for spread regimes, the same small set of endpoints powers your entire workflow: /symbols to discover, /latest to screen, /timeseries to validate, /electricity/hourly to refine, and /status to stay resilient.
If your roadmap includes cross‑hub spreads, clean spark overlays, or pan‑EU dashboards, start with the examples above and adapt the snippets into your stack. The developer‑friendly, normalized schema will let you ship in hours instead of weeks. Explore more at Energy API and get hands‑on today: Try Energy API for free.
Ready to get started?
Get your API key and start querying energy commodity prices in minutes.
Get API KeyRelated posts
Unlock trading success with our Finance API insights. Learn to optimize P&L using real-time spread and basis a...
Read more →
Unlock profitability in energy arbitrage with effective strategies for traders using Energy API. Discover how...
Read more →
Discover how to effectively benchmark intraday trading algorithms using Finance API market feeds and synthetic...
Read more →
Discover how Energy API is transforming decentralized energy markets, providing developers and traders with re...
Read more →
Discover how Energy API is transforming electric vehicle charging networks, offering developers and utilities...
Read more →