API-Driven Retail Tariff Optimization for Utilities: Implementing Dynamic Time-of-Use Plans to Minimize Customers’ Bills and Peak Demand Charges
In retail electricity, static tariffs are breaking under the weight of volatile wholesale markets, rooftop PV adoption, and rising grid constraints. Utilities need to minimize customers’ bills and simultaneously manage peak demand charges—without asking every household to become a market analyst. Developers at retailers and DSOs are being asked to ship dynamic Time-of-Use (TOU) plans, real-time bill estimators, and load-shifting nudges—but the raw data lives behind a patchwork of national portals, each with its own format, timezone quirks, and naming conventions.
This post shows how an API-driven approach turns that chaos into a streamlined, testable pipeline for dynamic tariff optimization. Using the unified JSON surface from Energy API, you can pull day-ahead curves, PVPC retail references, emissions intensity, and complementary commodities (gas, oil, coal, carbon allowances) with the same schema. We’ll implement a developer-friendly design for TOU rate construction, bill minimization logic, and peak shaving strategies—then we’ll walk through the exact endpoints to use, the JSON you’ll receive, and how to wire it into production applications with confidence and observability.
By the end, you’ll have a practical blueprint for building dynamic tariffs, running cost simulations, alerting users of low-price windows, and quantifying the emissions benefits of shifting loads—while eliminating months of ETL work and “screen scraping” public portals.
Why Energy API
Utilities and energy product teams need reliable inputs that can be shipped to production fast. The problem is data sprawl: OMIE for Spain day-ahead auctions, ENTSO-E for cross-border electricity, EIA/FRED for North American series, ESIOS for Spain’s PVPC references, and a half-dozen CSV flavors in between. Energy API solves this by normalizing official wholesale and grid datasets into one consistent JSON interface. Here are the developer-centric advantages that matter when you’re on a deadline:
- One normalized REST surface across commodities and providers. Whether you’re fetching OMIE day-ahead prices or EUA carbon allowances, you call the same verbs and parse the same field shapes. That saves days of writing bespoke extractors, schema mappers, and timezone adjusters.
- Broad coverage with consistent symbols. You don’t have to remember a dozen naming idiosyncrasies: electricity symbols like OMIE_ES_DA and PVPC_ES_2TD use the same semantics as gas (TTF_GAS, HENRY_HUB), oil (BRENT_CRUDE, WTI_CRUDE), coal (COAL_ROTTERDAM), and CO2 (EUA_CO2). Query multiple commodities in one call to drive hedging logic or blended cost calculations.
- Purpose-built endpoints for intraday curves and retail references. For TOU planning and real-time billing, you need hourly or 15-minute granularity where available. Energy API exposes endpoints that return full curves (e.g., electricity/hourly) and retail references like PVPC without scraping.
- Unified timeseries and forecasting semantics. Day-ahead auction results are available through deterministic forecasts (no black-box ML), and the same timeseries schema powers charts, regressions, and volatility analysis across assets—essential when your product blends grid price and emissions signals.
The result is a significantly smaller integration surface, less integration drift, and more shared code across your pricing, forecasting, and billing stacks.
Quick Start
All endpoints are served from:
Base URL: https://energy-api.com/api/v1
Authentication is provided via an api_key query parameter. The same pattern applies to every endpoint covered below.
Let’s make our first request: fetch the latest values for a few diverse symbols in a single call—Brent crude, TTF gas, and EU ETS allowances. Being able to mix categories in one response is invaluable for cost-of-service models that reference multiple fuel inputs.
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 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 status indicator for easy branching.
- date: The unified “as-of” reference date for the aggregated payload.
- rates: Latest numeric values keyed by symbol—notice mixed commodities in one object.
- dates: Per-symbol effective dates (useful when some markets publish on a different calendar).
- currencies: Currency codes per symbol to drive on-the-fly conversions in your UI or billing microservice.
With one straightforward payload, you can inform upstream optimization logic and display up-to-date commodity references for energy cost modeling and reporting.
Core Endpoints for Dynamic TOU Tariffs
Dynamic TOU optimization and peak demand minimization rely on knowing tomorrow’s price curve, understanding today’s retail reference, tracking long-term trends, and converting that into actionable cost estimates. These endpoints cover the full journey from raw market signals to customer-ready price plans.
1) GET /electricity/hourly — Intraday Curves for Day-Ahead Planning
Purpose: Fetch the full hourly (or 15-minute where available) curve for a given electricity symbol and date. You’ll use this to construct TOU blocks, compute bill impacts for a typical household profile, and generate optimal charge/discharge schedules for storage.
Path: /electricity/hourly
Key params:
- symbol (required): e.g., OMIE_ES_DA for Spain day-ahead.
- date (required): YYYY-MM-DD (target day for the curve).
curl -G https://energy-api.com/api/v1/electricity/hourly \
--data-urlencode "symbol=OMIE_ES_DA" \
--data-urlencode "date=2026-06-12" \
--data-urlencode "api_key=YOUR_API_KEY"
Example response (illustrative):
{
"success": true,
"symbol": "OMIE_ES_DA",
"date": "2026-06-12",
"frequency": "hourly",
"unit": "EUR/MWh",
"curve": [
{ "start": "2026-06-12T00:00:00+02:00", "end": "2026-06-12T01:00:00+02:00", "value": 62.10 },
{ "start": "2026-06-12T01:00:00+02:00", "end": "2026-06-12T02:00:00+02:00", "value": 59.40 },
{ "start": "2026-06-12T02:00:00+02:00", "end": "2026-06-12T03:00:00+02:00", "value": 56.30 }
// ... remaining intervals for the day
],
"timezone": "Europe/Madrid",
"provider": "omie"
}
Field meanings:
- curve: Array of time-bounded intervals with numeric values—ideal for direct overlap with a customer’s hourly usage to compute energy charges precisely.
- timezone: Use to align user local time, device scheduling, and bill segments. Never assume UTC in retail contexts.
- frequency: Indicates whether the granularity is hourly or 15-min; normalize your tariff logic accordingly.
Practical use: Build 3-block TOU plans (Off-Peak, Mid-Peak, Peak) by clustering adjacent hours around the lowest and highest quartiles. Compute a customer-specific bill by multiplying each interval’s kWh by the interval cost. You can also calculate the savings from shifting discretionary loads (HVAC pre-cooling, EV charging) out of the top decile hours to minimize peak demand contributions.
2) GET /electricity/pvpc — Spain PVPC Retail Reference
Purpose: Retrieve Spain’s PVPC hourly retail reference to benchmark your dynamic plan. Even if you’re constructing a custom tariff, anchoring your rate against PVPC helps keep offers competitive and transparent.
Path: /electricity/pvpc
Key params:
- date (required): YYYY-MM-DD.
curl -G https://energy-api.com/api/v1/electricity/pvpc \
--data-urlencode "date=2026-06-12" \
--data-urlencode "api_key=YOUR_API_KEY"
Example response (illustrative):
{
"success": true,
"date": "2026-06-12",
"symbol": "PVPC_ES_2TD",
"unit": "EUR/MWh",
"curve": [
{ "hour": "00:00-01:00", "value": 118.5 },
{ "hour": "01:00-02:00", "value": 115.2 },
{ "hour": "02:00-03:00", "value": 112.9 }
// ... 24 values
],
"country_code": "ES",
"provider": "esios"
}
How to use it:
- Benchmark: Compare your computed wholesale pass-through costs (e.g., OMIE_ES_DA + margin) with PVPC values to evaluate competitiveness by hour.
- Explainability: Show end users a chart overlay of PVPC vs. your dynamic plan and highlight where your plan saves money.
- Risk controls: Set safeguards so your price never exceeds PVPC by more than a defined margin during peak hours.
3) GET /forecast — Deterministic Day-Ahead Auction Results
Purpose: Retrieve the next published day-ahead auction price for supported electricity symbols. This is not a predictive model; it is a deterministic lookup for already-published auction data—perfect for staging tomorrow’s TOU rates automatically at publish time.
Path: /forecast
Key params:
- symbol (required): 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 response (illustrative):
{
"success": true,
"symbol": "EPEX_DE_DA",
"target_date": "2026-06-12",
"frequency": "hourly",
"timezone": "Europe/Berlin",
"unit": "EUR/MWh",
"curve": [
{ "start": "2026-06-12T00:00:00+02:00", "end": "2026-06-12T01:00:00+02:00", "value": 64.8 },
{ "start": "2026-06-12T01:00:00+02:00", "end": "2026-06-12T02:00:00+02:00", "value": 61.7 }
// ... 24 intervals
]
}
Implementation notes:
- Use this endpoint in a scheduled job to populate tomorrow’s TOU blocks immediately after auction publication. That ensures pricing is in front of customers before midnight without human intervention.
- Set validation gates: when forecast.success is true and curve length equals expected intervals (24 for hourly), persist to your tariff store.
- Use timezone to correctly map intervals to local clocks—especially relevant around DST changes.
4) GET /timeseries — Historical Series for Tariff Backtesting
Purpose: Pull historical series for electricity or any commodity to backtest your dynamic tariff rules. For example, quantify savings versus flat rate across the last 12 months or measure volatility to set peak/off-peak spreads.
Path: /timeseries
Key params:
- start (required), end (required): YYYY-MM-DD.
- symbols (required): One or more, comma-separated (mix categories if needed).
curl -G https://energy-api.com/api/v1/timeseries \
--data-urlencode "start=2025-01-01" \
--data-urlencode "end=2025-03-31" \
--data-urlencode "symbols=BRENT_CRUDE,TTF_GAS" \
--data-urlencode "api_key=YOUR_API_KEY"
Sample response (truncated from reference):
{
"success": true,
"base": "MIXED",
"start_date": "2025-01-01",
"end_date": "2025-03-31",
"rates": {
"BRENT_CRUDE": {
"2025-01-02": 76.30,
"2025-01-03": 75.90
},
"TTF_GAS": {
"2025-01-02": 46.80,
"2025-01-03": 47.10
}
},
"frequencies": {
"BRENT_CRUDE": "daily",
"TTF_GAS": "daily"
},
"currencies": {
"BRENT_CRUDE": "USD",
"TTF_GAS": "EUR"
}
}
Practical use:
- Backtest dynamic tariff heuristics on historical electricity prices. For regions with hourly curves, pair /timeseries with /electricity/hourly where needed.
- Incorporate gas and oil series to explain retail price context to customers during marketing or to tune hedge strategies that support stable retail margins.
- Use frequencies and currencies metadata to standardize units before aggregating monthly KPIs.
5) GET /fluctuation — Range Analysis for Peak/Off-Peak Definitions
Purpose: Evaluate start/end values, absolute change, and percentage change for a period. For TOU design, it clarifies volatility bands used to set block spreads (e.g., off-peak discount vs peak markup).
Path: /fluctuation
Key params:
- start (required), end (required): YYYY-MM-DD.
- symbols (required): One or more.
curl -G https://energy-api.com/api/v1/fluctuation \
--data-urlencode "start=2025-09-01" \
--data-urlencode "end=2025-09-30" \
--data-urlencode "symbols=OMIE_ES_DA,EUA_CO2" \
--data-urlencode "api_key=YOUR_API_KEY"
Example response (illustrative):
{
"success": true,
"base": "MIXED",
"period": { "start": "2025-09-01", "end": "2025-09-30" },
"results": {
"OMIE_ES_DA": {
"start_value": 93.5,
"end_value": 101.2,
"change": 7.7,
"change_pct": 8.24
},
"EUA_CO2": {
"start_value": 64.1,
"end_value": 67.8,
"change": 3.7,
"change_pct": 5.77
}
}
}
How to use it:
- Set guardrails for your TOU spreads (e.g., Peak price must not exceed Off-Peak by more than X%, unless monthly fluctuation exceeds threshold Y).
- Signal to risk and trading teams when volatility increases, prompting hedge adjustments or changes to customer-facing advice.
6) POST /cost-estimate — Sanity-Check Retail Plans
Purpose: Estimate a quick monthly power cost using latest wholesale price times a kWh/month input for a country or symbol. While it is a simplified calculation (excludes taxes, network charges, or hourly profile), it’s excellent for immediate feedback loops and pre-qualification flows.
Path: /cost-estimate
Key body params:
- symbol OR country (one required): For electricity, pass a symbol like OMIE_ES_DA or pass a country code that maps to a default symbol.
- kwh_per_month (required): Numeric monthly consumption.
curl -X POST https://energy-api.com/api/v1/cost-estimate \
-H "Content-Type: application/json" \
-d '{
"symbol": "OMIE_ES_DA",
"kwh_per_month": 350
}'
Example response (illustrative):
{
"success": true,
"symbol": "OMIE_ES_DA",
"kwh_per_month": 350,
"latest_price": 98.2,
"unit": "EUR/MWh",
"estimated_monthly_cost": 34.37,
"notes": "Estimate excludes taxes, network charges, and profile effects."
}
Use this to validate that your proposed TOU discounts have roughly the expected magnitude. For a real tariff, you’ll compute a weighted sum across the hourly curve and customer load profile—still, this call is perfect for real-time UX feedback and sales funnels.
7) GET /symbols and GET /latest — Discovery and Real-Time Anchors
Symbols lists the available assets by category, provider, and country. Latest retrieves the most recent values for one or many symbols at once—great for dashboards and system sanity checks.
Symbol discovery:
curl -G https://energy-api.com/api/v1/symbols \
--data-urlencode "category=electricity" \
--data-urlencode "api_key=YOUR_API_KEY"
Example response (truncated):
{
"success": true,
"count": 3,
"symbols": [
{
"symbol": "OMIE_ES_DA",
"name": "OMIE Spain Day-Ahead",
"category": "electricity",
"country_code": "ES",
"currency_code": "EUR",
"frequency": "hourly",
"description": "OMIE day-ahead auction price."
},
{
"symbol": "EPEX_DE_DA",
"name": "EPEX Germany Day-Ahead",
"category": "electricity",
"country_code": "DE",
"currency_code": "EUR",
"frequency": "hourly",
"description": "EPEX DE day-ahead auction price."
}
]
}
These metadata let you build symbol pickers, country-driven defaults, and automated unit selection in your calculators.
From Data to Action: Implementing Dynamic TOU and Peak Minimization
Let’s turn these endpoints into a repeatable pipeline that yields customer savings and lower system peaks. The high-level flow:
- Fetch tomorrow’s auction curve via /forecast for your market (e.g., OMIE_ES_DA).
- Cluster the curve into TOU blocks: Off-Peak (lowest quartile hours), Mid-Peak (middle 50%), Peak (highest quartile). Enforce contiguity where possible to simplify customer communication.
- Overlay customer profile: Multiply each hour’s price by expected kWh (use historical smart meter data or model-based profiles).
- Minimize bill subject to constraints: For flexible loads (EV, DHW, storage), shift energy out of peak windows and cap simultaneous load to avoid demand charges where applicable.
- Compare against reference tariffs: Pull /electricity/pvpc as a market benchmark and show transparent savings.
- Validate and publish: Use /status to check provider pipeline health and push the tariff only when data quality gates pass.
For peaky months, augment with /fluctuation to adapt the spread between blocks, ensuring you capture enough margin on peaks while offering real value off-peak. For longer-term calibration and narrative, fold in /timeseries across multiple commodities to explain drivers and maintain customer trust.
Code Examples: Fetch, Normalize, and Optimize
Below are simple JavaScript and Python examples to pull curves and compute a minimal illustrative TOU block assignment. Replace with your production-grade optimizer, but the structure shows how to bind Energy API responses directly into your logic.
JavaScript: Build TOU Blocks from Day-Ahead
async function fetchForecast(symbol, apiKey) {
const params = new URLSearchParams({ symbol, api_key: apiKey });
const res = await fetch(`https://energy-api.com/api/v1/forecast?${params.toString()}`);
if (!res.ok) throw new Error(`Forecast fetch failed: ${res.status}`);
const data = await res.json();
if (!data.success || !data.curve || !Array.isArray(data.curve)) {
throw new Error("Malformed forecast response");
}
return data;
}
function assignTouBlocks(curve) {
// curve: [{ start, end, value }]
const sorted = [...curve].sort((a, b) => a.value - b.value);
const n = sorted.length;
const q = Math.floor(n / 4);
const offPeakSet = new Set(sorted.slice(0, q).map(i => i.start));
const peakSet = new Set(sorted.slice(n - q).map(i => i.start));
return curve.map(i => {
const key = i.start;
const block = offPeakSet.has(key) ? "OFF" : (peakSet.has(key) ? "PEAK" : "MID");
return { ...i, block };
});
}
(async () => {
const apiKey = "YOUR_API_KEY";
const symbol = "OMIE_ES_DA";
const forecast = await fetchForecast(symbol, apiKey);
const withBlocks = assignTouBlocks(forecast.curve);
console.log(withBlocks.slice(0, 3));
})();
This snippet ranks hours by price and labels quartiles as OFF, MID, and PEAK. Production systems typically add contiguity constraints, minimum block lengths, and customer-experience overrides (e.g., avoid frequent block switching at meal times).
Python: Bill Estimation with Load Shifting
import requests
from datetime import datetime
def fetch_hourly(symbol, date, api_key):
params = {"symbol": symbol, "date": date, "api_key": api_key}
r = requests.get("https://energy-api.com/api/v1/electricity/hourly", params=params, timeout=20)
r.raise_for_status()
data = r.json()
if not data.get("success"):
raise RuntimeError("API returned unsuccessful response")
return data
def estimate_bill(curve, hourly_kwh, max_shift_kwh=8.0):
# naive: shift 'max_shift_kwh' from top decile hours to bottom decile, 1 kWh per hour
hours = list(curve)
hours.sort(key=lambda x: x["value"])
bottom = hours[:max(1, len(hours)//10)]
top = hours[-max(1, len(hours)//10):]
# Example profile: constant 1 kWh/hour baseline
profile = {h["start"]: hourly_kwh for h in curve}
# Shift energy
shift = min(max_shift_kwh, len(top), len(bottom))
for i in range(int(shift)):
top_hour = top[-(i+1)]["start"]
bottom_hour = bottom[i]["start"]
if profile[top_hour] > 0.2: # keep some load
profile[top_hour] -= 1.0
profile[bottom_hour] += 1.0
# Compute cost
total_cost = 0.0
for h in curve:
kwh = profile[h["start"]]
eur_per_mwh = h["value"]
eur_per_kwh = eur_per_mwh / 1000.0
total_cost += eur_per_kwh * kwh
return round(total_cost, 2)
if __name__ == "__main__":
api_key = "YOUR_API_KEY"
date = "2026-06-12"
symbol = "OMIE_ES_DA"
data = fetch_hourly(symbol, date, api_key)
cost = estimate_bill(data["curve"], hourly_kwh=1.0, max_shift_kwh=8.0)
print("Estimated daily energy cost (EUR):", cost)
In practice, replace the simple shift heuristic with your flexibility model: EV SOC constraints, water tank thermal storage, or HVAC thermal inertia. The core insight remains: the hourly curve from Energy API is directly consumable for optimization without ETL pain.
Error Handling, Health Checks, and Reliability Patterns
Production tariff engines need defensive coding. The API uses structured error responses and exposes health status by provider.
- 401 — Missing or invalid api_key.
- 404 — No data for the given symbols or date (e.g., pre-publication or holiday gap).
- 422 — Validation error (e.g., missing required parameter, invalid date).
- 429 — Rate limit exceeded. Implement exponential backoff with jitter and retry budgets.
Error response shape:
{
"success": false,
"error": "Human-readable message."
}
Provider health:
curl -G https://energy-api.com/api/v1/status \
--data-urlencode "api_key=YOUR_API_KEY"
Example response (illustrative):
{
"success": true,
"providers": [
{
"name": "omie",
"last_fetch": "2026-06-11T13:02:15Z",
"status": "ok",
"latency_ms": 410
},
{
"name": "esios",
"last_fetch": "2026-06-11T13:03:02Z",
"status": "ok",
"latency_ms": 520
},
{
"name": "eia",
"last_fetch": "2026-06-11T12:59:44Z",
"status": "ok",
"latency_ms": 680
}
]
}
Use GET /status in readiness checks and circuit breakers. For example, if OMIE unexpectedly shows degraded status, defer rate publication, notify on-call, and fall back to last-known-good curve with a visible banner in internal tools.
Real-World Use Cases
1) Dynamic TOU Plan Builder and Publisher
Use GET /forecast to fetch tomorrow’s hourly curve for OMIE_ES_DA or EPEX_DE_DA. Cluster intervals into 3–4 tariff blocks, then run a constraints-based optimizer to ensure customer bills drop versus their historic flat rates. Validate against GET /electricity/pvpc as a competitive benchmark. Publish the blocks and effective times to your billing engine and mobile UI, caching the source curves for auditing.
2) Peak Demand Minimization for EV Fleets
Pull GET /electricity/hourly for the relevant region every day. Combine with CARBON_INT_DE or CARBON_INT_EU from GET /carbon-intensity to prioritize low-carbon hours when tie-breaking between equal-cost windows. Build a scheduler that staggers charge sessions to flatten the fleet demand profile. Use GET /fluctuation monthly to adjust peak/off-peak spreads in the tariff offered to fleet customers.
3) Customer Bill Simulator with Explainability
Use GET /electricity/hourly plus a customer’s historic hourly load to compute a synthetic bill under the proposed TOU vs a reference flat rate. Query GET /latest for EUA_CO2 and TTF_GAS and display a concise explanation: “Your off-peak discount increased this month due to lower gas prices and subdued CO2 allowances.” Exposing commodity context improves trust and adoption.
FAQ
How often does the TTF gas price update?
TTF_GAS is ingested from official sources and normalized by Energy API. You can query GET /latest for the most recent price, or use GET /historical and GET /timeseries to obtain specific days and ranges. Always consult per-symbol dates in the response to understand publication timing.
Can I retrieve hourly electricity prices for tomorrow?
Yes. Use GET /forecast for auction-sourced symbols like OMIE_ES_DA or EPEX_DE_DA. The endpoint returns the next published day-ahead curve (deterministic, not predictive), including frequency, unit, and timezone for safe scheduling.
Does the API support multiple commodities in one request?
Yes. Endpoints like GET /latest and GET /timeseries accept multiple symbols across electricity, gas, oil, coal, carbon allowances, and carbon intensity. This is useful when you need to inform tariffs or dashboards with cross-commodity context in one round-trip.
How do I compute a customer’s monthly bill from hourly curves?
Fetch the hourly curve via GET /electricity/hourly (or /forecast for tomorrow), align to the user’s timezone, and multiply each interval’s kWh by the interval price (convert EUR/MWh to EUR/kWh by dividing by 1000). Sum over the billing period, then add your tariff components. For explainability, overlay PVPC (GET /electricity/pvpc) as a benchmark.
What happens if a market doesn’t publish on a given day?
GET /historical returns the most recent value before a non-publishing day. For intraday curves, rely on GET /forecast for auction-based symbols and handle 404 if data isn’t yet available; implement retry/backoff and publish only when completeness checks pass.
End-to-End Example: Building a Daily Tariff Job
A typical daily job for a Spanish retailer might run at the OMIE auction publication time:
- Call GET /forecast?symbol=OMIE_ES_DA. Validate success and 24 intervals.
- Compute OFF/MID/PEAK blocks using quartiles; enforce a minimum block length of 2 hours to reduce cognitive load in customer communications.
- Estimate customer savings vs PVPC: call GET /electricity/pvpc for the same date, compute an index comparison, and store results.
- Generate guidance: “Charge your EV from 01:00–06:00 for the best rate.” Include CARBON_INT_EU to highlight low-carbon windows.
- Publish the tariff to your billing engine and cache original JSON responses for audit trails.
- Ping GET /status. If provider statuses are “ok,” mark the job green; else rollover to a hold state and alert.
The same template adapts easily to Germany (EPEX_DE_DA) or other markets. Thanks to a unified schema, the core logic doesn’t change; only the symbol and timezone do.
Additional Endpoints and Their Business Value
GET /electricity/latest — Market Snapshot for Operations
Pull all electricity symbols’ latest prices—useful for support teams and operational dashboards that need a quick picture of where markets stand now. Filter by country to tailor regional views.
GET /gas/latest — Gas Benchmarks for Hedging Narratives
Fetch TTF_GAS and HENRY_HUB in one call to contextualize power prices and fuel-switching dynamics. Display both in your analytics portal for internal stakeholders making hedging decisions.
GET /emissions/latest and GET /carbon-intensity — Decarbonization Signals
EUA_CO2 (allowance prices) informs carbon cost pass-through logic, while CARBON_INT_DE or CARBON_INT_EU indicates when the grid is cleanest. Combine these to create a “low-cost, low-carbon” charging badge in your app.
GET /ohlc — Volatility and Risk Visualization
Weekly or monthly candles for key symbols allow risk teams to visualize ranges and quickly spot regime shifts. Use open/high/low/close to annotate risk memos and investor updates, or flag when to revisit TOU spreads.
Detailed JSON Examples and Field Interpretation
This section consolidates multiple realistic responses and highlights how to interpret each field for tariff engineering.
Timeseries: Multi-Commodity Context
{
"success": true,
"base": "MIXED",
"start_date": "2025-04-01",
"end_date": "2025-04-30",
"rates": {
"OMIE_ES_DA": {
"2025-04-01": 86.2,
"2025-04-02": 88.9
},
"EUA_CO2": {
"2025-04-01": 65.1,
"2025-04-02": 64.7
}
},
"frequencies": {
"OMIE_ES_DA": "daily",
"EUA_CO2": "daily"
},
"currencies": {
"OMIE_ES_DA": "EUR",
"EUA_CO2": "EUR"
}
}
- rates: A per-symbol map keyed by date; align values to your monthly billing cycles.
- frequencies: Helps your visualizations and aggregations—some assets may publish intraday; this declares the canonical series frequency here.
- currencies: Drive conversions to your ledger or customer display currency.
Historical: Point-In-Time Backfills
{
"success": true,
"date": "2025-09-15",
"base": "MIXED",
"rates": {
"BRENT_CRUDE": 71.45,
"TTF_GAS": 36.20
},
"currencies": {
"BRENT_CRUDE": "USD",
"TTF_GAS": "EUR"
}
}
- Use GET /historical when you need to reconcile a specific day’s tariff logic with the commodity backdrop—e.g., explaining unusual peak spreads on a given date.
Latest: Cross-Commodity Anchors for UI
{
"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"
}
}
- Expose these anchor values in ops dashboards to give everyone a shared reference frame while discussing pricing changes or customer comms.
Electricity Hourly: Tariff Engine Input
{
"success": true,
"symbol": "OMIE_ES_DA",
"date": "2026-06-12",
"frequency": "hourly",
"unit": "EUR/MWh",
"curve": [
{ "start": "2026-06-12T00:00:00+02:00", "end": "2026-06-12T01:00:00+02:00", "value": 62.10 },
{ "start": "2026-06-12T01:00:00+02:00", "end": "2026-06-12T02:00:00+02:00", "value": 59.40 }
],
"timezone": "Europe/Madrid",
"provider": "omie"
}
- Convert EUR/MWh to EUR/kWh by dividing by 1000 for cost computations.
- Always align to timezone before matching customer usage intervals.
Best Practices: Performance, Observability, and Governance
Even though you integrate one service, you should still build your internal platform with the same rigor you’d apply to any production data pipeline:
- Retries and backoff: Implement exponential backoff with jitter for 429 and transient 5xx. Use idempotent retry semantics for GET calls and ensure POST /cost-estimate calls are wrapped with client-side timeouts.
- Health checks and circuit breakers: Call GET /status prior to scheduled tariff publications. If a provider shows “degraded,” trip a circuit breaker that pauses publication and falls back to last-known-good.
- Regional latency and caching: Cache stable responses for the daily curve and symbols metadata; only refetch when data is expected to change (e.g., after auction publish windows).
- Auditability: Store original JSON payloads with hashes alongside your computed TOU blocks. This supports post-mortems and regulatory audits.
- Role separation: Organize access in your own systems by app roles—tariff-generation microservice vs analytics dashboard—so changes and queries are traceable.
These practices make your TOU engine resilient, transparent, and easy to evolve as you add new markets or incorporate emissions-aware scheduling.
Troubleshooting Patterns
- Missing intervals: If /electricity/hourly or /forecast returns fewer intervals than expected, treat it as incomplete. Do not publish rates until the curve is complete. Retry with backoff for a short window.
- Timezone surprises: Always use the provided timezone field. Store times as ISO-8601 strings and convert in the UI. DST boundary days require special handling to avoid off-by-one-hour billing errors.
- Currency mismatches: Before aggregating across commodities, standardize currency. Use the currencies object to determine which conversions you need for unified reporting.
- Non-publishing days: For GET /historical, the result may reflect the most recent business day. Document this in your BI layer so analysts interpret gaps correctly.
Conclusion + CTA
Dynamic TOU plans and peak demand minimization succeed or fail on the quality and timeliness of their inputs. By unifying electricity curves, retail references, emissions intensity, and cross-commodity context behind a single normalized JSON interface, Energy API removes integration friction and lets your team focus on optimization, user experience, and measurable savings.
From fetching tomorrow’s auction curve to benchmarking against PVPC and simulating bills with real customer profiles, you can move from prototype to production in days—not months of scraping, reconciling formats, and hardening brittle ETL. Add robust health checks, audit trails, and backtesting to build trust with operations, risk, and customers alike.
If you’re ready to ship API-driven TOU plans, real-time bill estimators, and low-carbon charging guidance, start now with the unified endpoints covered here. Try Energy API for free and make dynamic tariffs a competitive advantage for your customers and your grid.
Ready to get started?
Get your API key and start querying energy commodity prices in minutes.
Get API KeyRelated posts
Discover how Energy API streamlines meter-to-bill reconciliation for utilities, automating netting, tariff rul...
Read more →
Unlock the potential of Energy API to create personalized tariffs and targeted efficiency programs. Discover h...
Read more →
Discover how to optimize your EV fleet charging with an Energy API. Learn dynamic tariff selection and vehicle...
Read more →
Discover how Energy API can transform demand response programs for utilities. Enhance decision-making and opti...
Read more →
Discover how Energy API can transform your pricing strategies with dynamic tariff structures. Unlock real-time...
Read more →