Detecting and Investigating Smart-Meter Tampering at Scale: Building an Anomaly Investigation Pipeline with Energy API and Graph Analytics
Smart meters have transformed how utilities, retailers, and grid operators understand consumption — delivering granular, near-real-time data from millions of endpoints. But with that scale comes an uncomfortable truth: tampering, meter bypass, and instrumentation faults can quietly distort billing accuracy, grid-balancing forecasts, and demand response KPIs. Manual audits don’t scale, and blind spots around pricing context produce floods of false positives. If you’ve ever tried to investigate anomalies without timely market backdrops — like day-ahead electricity prices, intraday curves, gas benchmarks, or grid carbon intensity — you know how quickly “suspicious” usage can look normal once price signals, temperature, or fuel-switching incentives are factored in.
This post shows how to design a robust anomaly investigation pipeline for smart meter fleets by fusing meter telemetry with wholesale market context from Energy API. We’ll map a complete workflow: detecting behavioral breaks at the meter level, enriching with day-ahead and intraday electricity curves, correlating with gas and carbon price regimes, and assembling a graph of related meters, addresses, and tariffs to pinpoint coordinated tampering. Along the way, we’ll use a handful of JSON endpoints that normalize disparate providers (OMIE, ENTSO-E, EIA/FRED, ESIOS, Ember) behind one consistent REST surface so you can ship analytics in hours instead of weeks of scraping and ETL.
You’ll leave with working cURL examples, JSON payload breakdowns, and design patterns to reduce false positives and prioritize the cases that matter. Whether you’re a utility data engineer, a retail tariff analyst, a fintech risk team, or an ESG product owner, the same blueprint applies: the fastest path to reliable energy market context is to pull it from a single normalized interface and wire it straight into your meter anomaly graphs.
Why Energy API
Smart-meter anomaly pipelines live or die on context: what was the local day-ahead price profile? Did intraday prices spike during the anomaly window? Are retail reference rates shifting? Do fuel cross-elasticities (gas vs electricity) explain the break? Doing this with raw provider portals is brittle — formats differ, schedules vary by market, symbol naming drifts, and partial outages are common. Energy API removes that friction with one normalized JSON schema across electricity, gas, oil, coal, carbon allowances, and grid carbon intensity. Here’s why that matters for investigators and engineers.
- One normalized REST surface for every commodity. Instead of juggling OMIE XML for Spain, ENTSO-E CSVs for Central Europe, and EIA/FRED series for US fuel benchmarks, you ask for symbols by name and always get the same JSON shape. That means your enrichment jobs and feature stores don’t need per-provider parsers.
- Intraday electricity curves where sources publish them. For anomaly timing, the hourly or 15-minute profile is critical: you can align suspicious meter windows with price ramps or negative-price hours to separate genuine load shifting from tampering. Energy API exposes curated /electricity/hourly series so you can align timestamps directly.
- Multi-commodity joins in a single request. You can fetch electricity, gas, and carbon signals together with /latest or /timeseries for synchronized enrichment. This trims IO, eliminates time drift bugs, and simplifies your pipelines.
- Operational reliability and observability. With a dedicated /status endpoint you can programmatically track provider health. Pair that with your own retries and circuit breakers to build a resilient enrichment pipeline that never ships stale context into your anomaly models.
Bottom line: if your team builds anomaly graphs or ML that hinge on market context, you need clean inputs, consistent schemas, and predictable updates. That’s exactly what the Energy API normalization layer provides so your engineers can spend time on analysis — not on scraping and post-hoc cleanup.
Quick Start
All endpoints are available under a single base URL and share the same parameter conventions. You’ll see how to request multiple commodities in one call and interpret the result.
Base URL:
https://energy-api.com/api/v1
Example: fetch the most recent prices for Brent crude, European TTF gas, and EU ETS carbon allowances to contextualize cross-commodity dynamics that may affect electricity wholesale pricing or suspected meter bypass.
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 guard for error handling.
- date: the logical report date for the aggregate response.
- rates: a symbol-indexed object with latest numeric values.
- dates: per-symbol publication dates to verify recency.
- currencies: currency code by symbol for correct conversions or aggregation logic.
Use this immediately as a real-time enrichment source in your anomaly service: for example, enrich suspicious load drops with TTF_GAS to see if heat pumps switched to gas during a price shock, or map EUA_CO2 regimes to marginal cost changes influencing local wholesale electricity prices.
Core Endpoints
In a smart-meter tampering investigation pipeline, you’ll combine discovery, latest snapshots, time-windowed context, intraday curves, and operational health tracking. Below are the primary endpoints you’ll wire together, plus additional category utilities that often show up in feature engineering or casework dashboards.
1) Discover active symbols with /symbols
Before you standardize your data model, enumerate the available symbols by category and provider metadata. This prevents brittle hardcoding and lets you auto-expand coverage when new regions or commodities are added.
curl -G https://energy-api.com/api/v1/symbols \
--data-urlencode "category=electricity" \
--data-urlencode "api_key=YOUR_API_KEY"
Example response (truncated for brevity):
{
"success": true,
"count": 4,
"symbols": [
{
"symbol": "OMIE_ES_DA",
"name": "OMIE Spain Day-Ahead Price",
"category": "electricity",
"country_code": "ES",
"currency_code": "EUR",
"frequency": "daily",
"description": "Day-ahead auction results from OMIE."
},
{
"symbol": "EPEX_DE_DA",
"name": "EPEX Germany Day-Ahead Price",
"category": "electricity",
"country_code": "DE",
"currency_code": "EUR",
"frequency": "daily",
"description": "Day-ahead auction results for Germany."
},
{
"symbol": "PVPC_ES_2TD",
"name": "Spain PVPC Retail Reference (2TD)",
"category": "electricity",
"country_code": "ES",
"currency_code": "EUR",
"frequency": "hourly",
"description": "ESIOS PVPC reference prices."
},
{
"symbol": "AEMO_NSW1",
"name": "Australia NSW Wholesale Electricity",
"category": "electricity",
"country_code": "AU",
"currency_code": "AUD",
"frequency": "hourly",
"description": "AEMO spot market series."
}
]
}
What to use it for:
- Dynamic configuration: hydrate dropdowns in your casework UI with accurate symbol names and metadata.
- Schema governance: validate symbol inputs from investigative notebooks before executing heavy joins.
- Feature store indexing: attach frequency and currency metadata to your features for correct resampling and conversions.
2) Get synchronized snapshots with /latest
For near-real-time enrichment, request cross-commodity signals in a single call. This reduces IO overhead and ensures a coherent view at a single logical timestamp.
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"
You’ll get a symbol-indexed rates map and per-symbol dates/currencies, just as shown in Quick Start. That unified schema lets your anomaly pipeline treat cross-commodity enrichment consistently, regardless of region or provider.
3) Build historical windows with /timeseries
Tampering investigation relies on temporal context: did a household’s consumption deviate on nights when prices were unusually low, or is there a persistent pattern across weeks? Use /timeseries to align wholesale or retail reference series to your analysis window.
curl -G https://energy-api.com/api/v1/timeseries \
--data-urlencode "start=2025-11-01" \
--data-urlencode "end=2025-12-15" \
--data-urlencode "symbols=OMIE_ES_DA,TTF_GAS,EUA_CO2" \
--data-urlencode "api_key=YOUR_API_KEY"
Sample JSON:
{
"success": true,
"base": "MIXED",
"start_date": "2025-11-01",
"end_date": "2025-12-15",
"rates": {
"OMIE_ES_DA": {
"2025-11-01": 61.20,
"2025-11-02": 55.10
},
"TTF_GAS": {
"2025-11-03": 42.75,
"2025-11-04": 43.10
},
"EUA_CO2": {
"2025-11-03": 68.90,
"2025-11-04": 69.25
}
},
"frequencies": {
"OMIE_ES_DA": "daily",
"TTF_GAS": "daily",
"EUA_CO2": "daily"
},
"currencies": {
"OMIE_ES_DA": "EUR",
"TTF_GAS": "EUR",
"EUA_CO2": "EUR"
}
}
Key fields and usage:
- rates: symbol → date → value map for time-window joins.
- frequencies: drive resampling logic when mixing hourly meter data with daily market series.
- currencies: standardize to a single currency before building monetary KPIs (e.g., estimated avoided cost).
4) Compute regime shifts with /fluctuation
When ranking anomaly cases, you’ll often want a compact measure of market context intensity: how much did TTF gas or EU ETS change during a meter’s anomalous spell? /fluctuation returns start/end values plus absolute and percent change.
curl -G https://energy-api.com/api/v1/fluctuation \
--data-urlencode "start=2025-12-01" \
--data-urlencode "end=2025-12-10" \
--data-urlencode "symbols=TTF_GAS,EUA_CO2,OMIE_ES_DA" \
--data-urlencode "api_key=YOUR_API_KEY"
Example response:
{
"success": true,
"base": "MIXED",
"start_date": "2025-12-01",
"end_date": "2025-12-10",
"fluctuations": {
"TTF_GAS": {
"start_value": 41.20,
"end_value": 44.05,
"change": 2.85,
"change_pct": 6.91
},
"EUA_CO2": {
"start_value": 67.50,
"end_value": 69.80,
"change": 2.30,
"change_pct": 3.41
},
"OMIE_ES_DA": {
"start_value": 58.40,
"end_value": 63.10,
"change": 4.70,
"change_pct": 8.05
}
}
}
Use change_pct as a covariate in your anomaly scoring to down-rank suspected tampering when price regimes were highly volatile and to up-rank outliers during stable periods.
5) Visualize and validate with /ohlc
Candles help analysts sanity-check trends and volatility regimes. Monthly or weekly OHLC is perfect for dashboards and quick triage when correlating meter anomalies with price environments.
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-12-31" \
--data-urlencode "api_key=YOUR_API_KEY"
Sample JSON:
{
"success": true,
"base": "MIXED",
"ohlc": {
"BRENT_CRUDE": [
{ "period": "2025-01", "open": 76.4, "high": 80.2, "low": 72.9, "close": 78.1, "data_points": 21 },
{ "period": "2025-02", "open": 78.1, "high": 82.0, "low": 75.5, "close": 79.3, "data_points": 19 }
],
"TTF_GAS": [
{ "period": "2025-01", "open": 46.7, "high": 50.1, "low": 44.8, "close": 47.2, "data_points": 20 },
{ "period": "2025-02", "open": 47.2, "high": 49.2, "low": 45.1, "close": 46.6, "data_points": 20 }
]
}
}
data_points is especially useful for confidence: fewer points in a period may reflect holidays or provider cadence; expose it alongside candles in your UI so investigators can trust visual inferences.
6) Intraday profile with /electricity/hourly
This is a cornerstone for tampering detection: align hourly or 15-minute wholesale curves to the precise windows where smart-meter behavior broke from norms. For day-ahead auction markets, these curves reflect published results per delivery hour.
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 response:
{
"success": true,
"symbol": "OMIE_ES_DA",
"date": "2025-09-15",
"interval": "hourly",
"currency": "EUR",
"curve": [
{ "time": "2025-09-15T00:00:00+02:00", "value": 56.1 },
{ "time": "2025-09-15T01:00:00+02:00", "value": 54.8 },
{ "time": "2025-09-15T02:00:00+02:00", "value": 53.7 }
]
}
Map curve.time to the local timezone for the meter region to compute incentive-aligned usage changes (e.g., unexpected load spikes in high-price hours could signal bypass of controlled loads).
7) Retail reference with /electricity/pvpc
Where applicable (e.g., Spain), PVPC hourly retail references give ground truth for consumer-facing incentives on a given day. Sequence them next to smart-meter profiles to distinguish opportunistic load shifting from physical tampering.
curl -G https://energy-api.com/api/v1/electricity/pvpc \
--data-urlencode "date=2025-09-15" \
--data-urlencode "api_key=YOUR_API_KEY"
Sample response:
{
"success": true,
"date": "2025-09-15",
"interval": "hourly",
"currency": "EUR",
"series": [
{ "hour": "00:00-01:00", "value": 0.1743 },
{ "hour": "01:00-02:00", "value": 0.1695 }
]
}
Use this series to derive per-hour expected savings for demand shifting features or to sanity-check if a customer had financial motivation to alter reported consumption at specific hours.
8) Cross-commodity aggregators: /gas/latest, /emissions/latest, /coal/latest
These shortcuts minimize symbol selection for common combinations and keep your enrichment calls concise when you only need category leaders.
curl -G https://energy-api.com/api/v1/gas/latest \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON:
{
"success": true,
"date": "2026-06-11",
"base": "MIXED",
"rates": {
"TTF_GAS": 38.15,
"HENRY_HUB": 2.83
},
"currencies": {
"TTF_GAS": "EUR",
"HENRY_HUB": "USD"
}
}
Add EUA price context:
curl -G https://energy-api.com/api/v1/emissions/latest \
--data-urlencode "api_key=YOUR_API_KEY"
And coal benchmarks:
curl -G https://energy-api.com/api/v1/coal/latest \
--data-urlencode "api_key=YOUR_API_KEY"
These category calls are ideal for nightly feature backfills or to frame weekly case review dashboards with a concise cross-commodity header.
9) Next published day-ahead with /forecast
For auction-sourced electricity symbols, you can fetch the next published day-ahead result (not a predictive model) to prime your schedule or compare provisional analytics.
curl -G https://energy-api.com/api/v1/forecast \
--data-urlencode "symbol=OMIE_ES_DA" \
--data-urlencode "api_key=YOUR_API_KEY"
Typical response:
{
"success": true,
"symbol": "OMIE_ES_DA",
"date": "2025-09-16",
"currency": "EUR",
"values": {
"base": 62.15
}
}
Use this to stage anomaly monitoring windows ahead of delivery, e.g., proactively allocate investigator capacity on days with steep expected ramps.
10) Grid carbon intensity with /carbon-intensity
Carbon intensity reveals grid mix dynamics that affect both costs and ESG-relevant behavior. It’s helpful context when a meter’s appliance usage (e.g., EV charging) suddenly shifts to hours with dirtier or cleaner grid profiles.
curl -G https://energy-api.com/api/v1/carbon-intensity \
--data-urlencode "country=DE" \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON:
{
"success": true,
"country": "DE",
"units": "gCO2eq/kWh",
"symbol": "CARBON_INT_DE",
"date": "2025-09-15",
"value": 398
}
Combine this with hourly electricity curves in your dashboards to flag anomalies that also degrade carbon KPIs.
11) Operational health with /status
Production pipelines need health checks. Before critical backfills or daily model runs, query /status to guard against partial outages upstream and trigger fallbacks or deferrals.
curl -G https://energy-api.com/api/v1/status \
--data-urlencode "api_key=YOUR_API_KEY"
Example JSON:
{
"success": true,
"providers": [
{ "name": "OMIE", "last_fetch": "2026-06-11T09:15:00Z", "status": "ok" },
{ "name": "ENTSO-E", "last_fetch": "2026-06-11T09:10:00Z", "status": "ok" },
{ "name": "ESIOS", "last_fetch": "2026-06-11T09:05:00Z", "status": "ok" },
{ "name": "EIA", "last_fetch": "2026-06-10T22:00:00Z", "status": "ok" },
{ "name": "FRED", "last_fetch": "2026-06-10T22:00:00Z", "status": "ok" }
]
}
Use status to trip a circuit breaker that halts new case scoring if a dependent provider is stale; resume automatically once status returns to ok.
12) Simple cost modeling with /cost-estimate
During casework, investigators often ask “what would this usage have cost at wholesale?” A quick multiplication helps spotlight unusually low apparent costs that don’t match metered load — a common tampering signal.
curl -X POST https://energy-api.com/api/v1/cost-estimate \
-H "Content-Type: application/json" \
-d '{
"symbol": "OMIE_ES_DA",
"kwh_per_month": 450
}'
Example JSON:
{
"success": true,
"symbol": "OMIE_ES_DA",
"kwh_per_month": 450,
"price": 60.85,
"currency": "EUR",
"estimated_monthly_cost": 27.38,
"notes": "Wholesale-only estimate; excludes taxes, network charges, and hourly profile effects."
}
Use it to benchmark accounts or to support investigator narratives; always present it as a wholesale-only approximation.
13) Error handling patterns (all endpoints)
Build robust clients by watching for 4xx/5xx response codes and standardized error bodies. Validate required params and use exponential backoff on transient errors. Sample error shape:
{
"success": false,
"error": "No data for the given symbols or date."
}
Common cases to handle gracefully:
- 404 for a non-publishing day across certain series — design your UI to show “last available” gracefully or to guide investigators to a nearby date.
- 422 for invalid formats or missing params — surface actionable messages to user forms in your internal tools.
- 429 for temporary throttling — implement exponential backoff and jitter in your client library.
Designing the Smart-Meter Tampering Investigation Pipeline
With the endpoints above, here’s a recommended architecture that pairs timeseries context with graph analytics. The goals: reduce false positives, rapidly converge on probable tampering clusters, and give investigators precise, defensible evidence.
-
Ingestion and normalization:
- Stream smart-meter reads (15-min or hourly) into a time-series database or data lake with proper timezone fidelity.
- Maintain a feature store keyed by meter_id, date, hour with columns for price curves (e.g., OMIE_ES_DA), PVPC hourly where applicable, carbon intensity, TTF_GAS, EUA_CO2, and aggregated indicators from /fluctuation.
-
Context enrichment jobs:
- Nightly: /timeseries for OMIE_ES_DA, EPEX_DE_DA, TTF_GAS, EUA_CO2; /ohlc for weekly dashboards; /status preflight with circuit breakers.
- Intraday: /electricity/hourly for the current delivery date; /electricity/pvpc for relevant countries; /gas/latest and /emissions/latest for cross-commodity context.
-
Feature engineering:
- Price-aligned elasticity features: usage_in_high_price_hours, usage_in_negative_price_hours, hour_of_max_delta_vs_median.
- Market regime features: ttf_change_pct_7d, eua_change_pct_14d, da_price_volatility_index from /fluctuation and /ohlc.
- Carbon-aware features: shift_to_low_intensity_hours, delta_vs_prior_week_intensity for customer’s region.
-
Graph construction:
- Build a graph where nodes are meters, addresses, customer accounts, and installers; edges represent spatial proximity, shared substation transformers, tariff similarity, and synchronized anomaly windows.
- Weight edges by contextual similarity: difference in hourly price incentive exposure, PVPC alignment, and gas/electricity substitution patterns.
-
Scoring and triage:
- Combine outlier detection (e.g., median absolute deviation on normalized usage) with market-aware adjustments. Penalize anomalies observed during extreme price volatility; elevate those that break incentives.
- Rank clusters by caseworthiness: larger connected components with aligned price-agnostic anomalies score higher.
-
Investigator dashboard:
- Display hourly price curves and meter reads overlaid, PVPC reference, market regime summaries, cost-estimate approximations, and carbon intensity toggles. Keep transparency high with data source and timestamps on every panel.
This architecture works because the Energy API normalizes every input you need, avoids per-country parsing logic, and keeps the shape of data consistent as you expand geographies and commodities. Your anomaly logic remains focused on the physics and economics — not on acquisition plumbing.
Code Walkthrough: Enrichment and Feature Engineering
Below are concise client patterns in Python and JavaScript to fetch context and write features that snap to your meter telemetry.
Python: fetch timeseries for electricity and gas, then compute a simple 7-day volatility feature.
import requests
from datetime import date, timedelta
BASE = "https://energy-api.com/api/v1"
API_KEY = "YOUR_API_KEY"
start = "2025-11-01"
end = "2025-12-15"
symbols = "OMIE_ES_DA,TTF_GAS"
r = requests.get(f"{BASE}/timeseries", params={
"start": start,
"end": end,
"symbols": symbols,
"api_key": API_KEY
})
data = r.json()
def pct_volatility(series):
# simple daily volatility proxy: average absolute day-over-day % change
values = [v for _, v in sorted(series.items())]
pct = []
for i in range(1, len(values)):
if values[i-1] != 0:
pct.append(abs((values[i] - values[i-1]) / values[i-1]) * 100.0)
return sum(pct) / len(pct) if pct else 0.0
features = {}
for sym, series in data["rates"].items():
features[f"{sym}_volatility_7d"] = pct_volatility(series)
print(features)
JavaScript: overlay hourly OMIE curve on a smart-meter’s daily profile.
const BASE = "https://energy-api.com/api/v1";
const API_KEY = "YOUR_API_KEY";
async function getHourlyCurve(symbol, date) {
const url = new URL(`${BASE}/electricity/hourly`);
url.searchParams.set("symbol", symbol);
url.searchParams.set("date", date);
url.searchParams.set("api_key", API_KEY);
const res = await fetch(url);
return res.json();
}
(async () => {
const hourly = await getHourlyCurve("OMIE_ES_DA", "2025-09-15");
// Suppose meterHours is [{ time: ISO, kwh: number }, ...]
// Align by hour and compute ratio kwh / price to examine incentive-consistent behavior
// Or visualize both series in your charting library.
console.log(hourly.curve.slice(0, 3));
})();
These snippets demonstrate small, composable patterns you can tuck into your ETL or investigative notebooks. The same approach generalizes to PVPC, carbon intensity, and cross-commodity snapshots with identical response shapes.
Real-World Use Cases
Below are common solutions teams ship on top of the Energy API to accelerate anomaly investigations and reduce OPEX.
-
Tampering case triage dashboard:
Enrich flagged meters with OMIE or EPEX hourly curves, PVPC where applicable, and TTF/EUA regimes. Use /electricity/hourly, /electricity/pvpc, /latest, and /timeseries to plot incentives next to actual usage and down-rank cases that follow rational customer behavior. -
Automated anomaly scorer with market-aware features:
Feed /fluctuation and /ohlc into your feature store to compute volatility-adjusted anomaly scores. Build alert thresholds that adapt to price turbulence so you don’t drown investigators in false positives during market spikes. -
ESG and carbon-aware incident review:
Blend /carbon-intensity with hourly curves and meter reads to identify anomalies that increase emissions footprint. Highlight cases where suspected tampering both violates tariff norms and worsens carbon KPIs.
FAQ
How often does the TTF gas price update?
TTF_GAS is exposed through a normalized interface with a daily frequency. You can always query the most recent observation via /gas/latest or pull a historical window with /timeseries; the response includes per-symbol dates so you can confirm recency and handle non-publishing days gracefully.
Can I query electricity, gas, and carbon in the same call?
Yes. /latest and /timeseries accept comma-separated symbols from different categories and return one uniform JSON object with per-symbol values, dates, and currencies. This is ideal for synchronized enrichment in your anomaly pipelines and avoids time drift between categories.
Do you provide intraday electricity curves for day-ahead markets?
Where sources publish them, you can retrieve full hourly (or 15-min) curves using /electricity/hourly. The response includes timestamped values you can align to the meter’s timezone and delivery date, enabling precise incentive analysis at the same granularity as your meter reads.
Can I get historical energy prices going back several years?
Use /timeseries with a start and end date to fetch historical series across electricity, gas, oil, coal, and carbon. The response includes frequency and currency metadata to simplify resampling and conversions when joining with hourly meter data.
What’s the best way to handle temporary data gaps or provider issues?
Query /status before critical jobs to detect upstream staleness and implement client-side retries with exponential backoff for transient issues. In dashboards, present “last available” dates from /latest or /historical and surface provider health so investigators understand any data-window limitations.
Putting It All Together: End-to-End Example Flow
Let’s walk a concrete flow for a European utility investigating a surge in anomaly flags across a distribution substation in Spain. The team suspects either coordinated tampering or a model blind spot during an unusual market regime.
-
Inventory symbols needed:
Call /symbols for electricity to confirm OMIE_ES_DA and PVPC availability. Store frequency and currency for downstream logic. -
Establish market backdrop:
Use /timeseries to fetch OMIE_ES_DA, TTF_GAS, and EUA_CO2 for the last 45 days; compute price volatility and directionality via /fluctuation. This frames whether anomalies occurred during steady or turbulent markets. -
Align intraday incentives:
For the suspect delivery days, call /electricity/hourly for OMIE_ES_DA and /electricity/pvpc for the same dates. Overlay on meter-level hourly profiles. -
Graph construction:
Build edges among meters with synchronized anomalies that defy price incentives (e.g., increased consumption in the top quartile of hourly prices across several consecutive days). Attach TTF/EUA deltas to edges as weights. -
Case ranking:
Score clusters higher if their behavior diverges from incentives in stable price regimes. Use /cost-estimate to quantify magnitude (approximate wholesale-only cost exposure) for triage prioritization. -
Operations guardrails:
Before your daily batch, query /status. If OMIE is stale, hold case generation to prevent mislabeling. When status returns ok, resume and backfill.
This approach lets your team separate “market-normal” oddities from genuine tampering patterns and scales across regions because the data shape never changes as you add EPEX_DE_DA or other markets.
Performance and Reliability Best Practices
-
Batch multi-commodity calls:
Favor /latest and /timeseries with comma-separated symbols to reduce HTTP round trips and ensure synchronized timestamps, minimizing race conditions in enrichment workers. -
Resampling discipline:
Electricity intraday curves are hourly or 15-min; day-ahead spot and many fuel series are daily. Join hourly meter data to the nearest delivery hour for electricity; broadcast daily series across all hours in that day separately. Use the frequencies field to drive this automatically. -
Circuit breakers and health checks:
Always consult /status at the start of scheduled jobs and after API exceptions; trip a breaker for affected providers and short-circuit dependent tasks. Log provider last_fetch timestamps for auditability. -
Exponential backoff with jitter:
Handle 429 and transient network errors by backing off and adding randomness to prevent thundering herds during brief provider hiccups. -
Idempotent ETL stages:
Store high-water marks (last successfully processed date per symbol) to replay safely after outages. Since responses are deterministic for a given date/symbol, idempotency is straightforward. -
Schema-first integrations:
Validate that your downstream consumers only rely on the stable keys (rates, dates, currencies, frequencies). Keep symbol lists in configuration you can refresh via /symbols to avoid code redeploys as you add markets.
Extended Endpoint Coverage for Investigators and Data Engineers
Below is a quick catalog of the broader endpoint surface and practical business value for anomaly pipelines, so you can plan your integrations comprehensively.
- /symbols: Discover available assets; build dynamic configs and validation rules.
- /latest: Cross-commodity snapshot for dashboards and streaming enrichment.
- /historical: Point-in-time queries for audits and “as of” investigations when a date falls on a non-publishing day; returns the closest available prior value.
- /timeseries: Core for charts, ML features, and case context windows across multiple commodities with the same response schema.
- /fluctuation: Compact start/end summary and percentage changes; drive risk-aware thresholds and score normalization.
- /ohlc: Weekly/monthly/quarterly candles; visualize volatility regimes, help analysts build intuition quickly.
- /electricity/latest: Fetch all electricity symbols quickly, useful to build region pickers or market overviews.
- /electricity/hourly: Intraday curves for alignment with meter reads; cornerstone of incentive-consistent anomaly analysis.
- /electricity/pvpc: Hourly retail reference for Spain; contextualize consumer incentives directly.
- /gas/latest: EU (TTF_GAS) and US (HENRY_HUB) leaders in one call; model cross-fuel substitution.
- /emissions/latest: EUA_CO2 benchmark; proxy marginal cost shifts and ESG context.
- /coal/latest: Coal benchmarks; complementary context for thermal stack analysis.
- /carbon-intensity: Grid intensity by country; quickly add ESG overlays to anomalies.
- /forecast: Next published day-ahead for auction symbols; schedule pre-emptive monitoring.
- /cost-estimate: Back-of-the-envelope wholesale cost; speed up investigator narratives.
- /status: Observability into provider freshness; automate guardrails and SLAs.
To anchor a few more payloads that investigators often need, here are additional complete examples.
/historical example for an audit date:
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"
}
}
/electricity/latest for a market overview:
curl -G https://energy-api.com/api/v1/electricity/latest \
--data-urlencode "api_key=YOUR_API_KEY"
{
"success": true,
"date": "2026-06-11",
"base": "EUR",
"rates": {
"OMIE_ES_DA": 63.80,
"EPEX_DE_DA": 58.10,
"PVPC_ES_2TD": 0.1712
},
"currencies": {
"OMIE_ES_DA": "EUR",
"EPEX_DE_DA": "EUR",
"PVPC_ES_2TD": "EUR"
}
}
/carbon-intensity by country to annotate emissions context:
curl -G https://energy-api.com/api/v1/carbon-intensity \
--data-urlencode "country=EU" \
--data-urlencode "api_key=YOUR_API_KEY"
{
"success": true,
"country": "EU",
"units": "gCO2eq/kWh",
"symbol": "CARBON_INT_EU",
"date": "2025-09-15",
"value": 265
}
These examples show consistent schemas that make your investigation code modular and low-risk.
Troubleshooting and Governance Tips
-
Schema drift protection:
Wrap API calls in small adapters that verify presence of success, rates or curve/series fields, and per-symbol currencies. Emit structured metrics on missing keys to catch upstream changes early. -
Timezone hygiene:
Intraday electricity payloads include ISO timestamps. Convert them to the meter’s local time and verify DST transitions explicitly to avoid off-by-one-hour artifacts in anomaly windows. -
Currency normalization:
Some symbols are USD, some EUR, AUD, etc. Always consult currencies in responses; choose a canonical base internally and convert once per load. -
Data lineage and audits:
Store the raw response blobs with a minimal metadata envelope (symbol, date, fetch_time, provider status snapshot) so investigators can click into “source of truth” evidence during case reviews. -
Backfills and late data:
Plan for backfills by keeping immutable partitions keyed by event_date and symbol. Re-run /timeseries for missing windows — since shapes are stable, your replay logic stays simple.
Conclusion + CTA
Detecting and investigating smart-meter tampering at scale is fundamentally a signal-to-noise challenge. Without market and grid context, every odd load curve looks suspicious; with the right prices, intraday profiles, and carbon indicators layered in, genuine tampering stands out fast. The engineering unlock is a normalized energy data surface that you can trust across geographies and commodities.
By consolidating electricity, gas, oil, coal, carbon, and carbon intensity into one JSON schema — with endpoints for intraday curves, timeseries, candles, fluctuations, and provider health — Energy API lets your team build anomaly investigation pipelines in hours, not weeks. Plug it into your enrichment jobs, graph analytics, and dashboards to slash false positives and elevate high-confidence cases.
Ready to power your investigation stack with reliable market context? Try Energy API for free and start wiring wholesale and carbon signals directly into your smart-meter analytics today.
Ready to get started?
Get your API key and start querying energy commodity prices in minutes.
Get API KeyRelated posts
Discover how to enhance grid operations by operationalizing anomaly detection with Energy API. Learn to catch...
Read more →
Discover how to implement OAuth2 consent flows and enhance customer data privacy with Energy API for secure me...
Read more →
Unlock the potential of Energy API to create personalized tariffs and targeted efficiency programs. Discover h...
Read more →
Discover how Energy API streamlines meter-to-bill reconciliation for utilities, automating netting, tariff rul...
Read more →
Discover how to build a synthetic smart-meter dataset generator using the Energy API for safe developer testin...
Read more →