Use day-ahead electricity prices
Electricity does not cost the same all day. On European wholesale markets a price is set for every hour of tomorrow, published the afternoon before — the day-ahead market. Between a cheap overnight hour and an expensive evening peak the difference is routinely several-fold, and occasionally the price goes negative.
For a fleet that charges overnight and is not in a hurry, moving load a few hours is one of the largest cost levers available.
Flowion collects these forecasts from ENTSO-E, the European transmission operators' platform, and serves them through the API.
Fetching prices#
Two ways to say which market you mean:
# By environment — uses its configured price zone
curl "https://api.flowion.io/v1/energy/prices?environment_id=$ENV" \
-H "Authorization: Bearer $TOKEN"
# By raw bidding zone EIC code
curl "https://api.flowion.io/v1/energy/prices?zone=10YSE-1--------K" \
-H "Authorization: Bearer $TOKEN"
Give exactly one of zone or environment_id. Optional from and to bound
the window — from defaults to now, to to 48 hours after it.
There is also a per-site variant, which matters when one environment spans several markets:
curl "https://api.flowion.io/v1/sites/$SITE/energy/prices" \
-H "Authorization: Bearer $TOKEN"
Reading a price point#
{
"period_start": "2026-08-11T02:00:00Z",
"resolution_minutes": 60,
"price_amount": "18.44",
"currency": "EUR"
}
Points come back chronological.
Two things to handle properly:
price_amount is a decimal string, not a number. Parse it as a decimal
type. Reading it as a float and rounding to cents will drift once you are
summing thousands of intervals.
Prices can be negative. When wind generation exceeds demand, producers pay
to offload it. "-5.32" is a real value, and a comparison that assumes
positive prices will pick the wrong hour precisely when the saving is biggest.
Do not assume resolution_minutes is always 60 either — European markets are
moving toward 15-minute settlement, and the field exists to tell you.
Bidding zones#
A bidding zone is a market area with a single clearing price, identified by an EIC code. Zones are not countries: Sweden has four, Norway five, Germany and Luxembourg share one.
Set the zone on the environment, or override it per site. A fleet spread across zones and priced against one of them will be wrong for every site except that one — often by a lot, because zonal prices diverge most exactly when the grid is stressed.
What you can do with it today#
The forecast is available data, not an automatic behaviour. Nothing in the platform currently shifts charging toward cheap hours by itself.
What you can build on it:
Report on it. Combine transaction energy with the prices that applied to work out what a session or a site actually cost.
Schedule with it. Fetch tomorrow's prices, find the cheapest window long enough for the energy you need, and install a charging limit whose schedule opens up during it and throttles outside it.
Decide with it. Choose when to start a queued session, or whether to accept a discretionary one now.
Price-optimized allocation is designed but not built. Making the load balancer weight its allocation by price — rather than you scheduling around it — is planned work, not current behaviour. See OCPP feature coverage.
A worked pattern#
The common overnight case, in four steps:
- Fetch prices from now to 48 hours out for the site's zone.
- Work out how much energy the connected vehicles need, from their transactions' recent meter readings.
- Find the cheapest contiguous window long enough to deliver it at the rate the circuit allows.
- Install a
default_policycharging limit whose schedule permits a full rate inside that window and a minimal rate outside it.
Re-run it when tomorrow's prices publish, in the afternoon.
Two things to build in from the start. Vehicles taper — a car near full
draws far less than its allowance, so a window sized from the ceiling will be
too short. And forecasts have an edge: past to, you have no prices, so a
schedule must degrade to something safe rather than to nothing.
Availability#
Data comes from ENTSO-E, so it covers European markets. An environment with no price zone configured returns nothing — that is an unset setting, not an error.
Collection runs on a timer. A gap around publication time is normal; treat a missing point as "not yet known", not zero.