Historical Victoria Electricity Prices
You need clean, historical Victoria spot electricity prices you can load into a financial model and chart reliably. By the end of this guide you will query, parse, and validate the Energy API timeseries for Victoria Electricity (AEMO_VIC1_SPOT) so you can automate backfills, compute averages and volatilities, and keep your dashboards current.
What you will build and what you need
You will build a small, copy-pasteable integration that fetches Victoria Electricity prices, reads the response fields correctly, and stores the values with the right unit and base currency semantics.
- API: Energy API timeseries endpoint (GET /api/v1/timeseries)
- Symbol: AEMO_VIC1_SPOT (Victoria Electricity)
- Auth: api_key query parameter using YOUR_API_KEY
- Unit: AUD/MWh
- Plan note: Starter $19.99/mo, trial 7 days / 50 calls
When you are ready, create an account here: Register. Keep the key private; this guide will only show YOUR_API_KEY placeholders.
Symbol, units, and endpoint details you must get right
For Victoria Electricity you will query exactly one symbol and treat all returned values in AUD/MWh:
- Symbol name: Victoria Electricity
- Symbol code: AEMO_VIC1_SPOT
- Unit: AUD/MWh
- Endpoint: https://energy-api.com/api/v1/timeseries
- Method: GET (use query parameters)
- Auth: api_key query parameter (YOUR_API_KEY)
The core query parameters are:
- start: ISO date (YYYY-MM-DD) defining the inclusive window start
- end: ISO date (YYYY-MM-DD) defining the inclusive window end
- symbols: comma-separated list of symbols; here use AEMO_VIC1_SPOT
- api_key: YOUR_API_KEY
Do not pass unrelated parameters. In particular, do not pass base=USD when you also need TTF_GAS or EUA_CO2. For Victoria Electricity you will rely on the base and currency fields that come back in the response.
Quick start: a copy-pasteable curl request
Run the official sample curl to see the endpoint shape and parameterization. Replace YOUR_API_KEY with your key when you run it against your account:
curl -G "https://energy-api.com/api/v1/timeseries" --data-urlencode "start=2026-01-01" --data-urlencode "end=2026-03-31" --data-urlencode "symbols=AEMO_VIC1_SPOT" --data-urlencode "api_key=YOUR_API_KEY"
Understand the fields you will actually use
Below is a real response block you can use as a reference for parsing Victoria Electricity. Copy the exact values for tests that require a stable fixture:
{"success":true,"date":"2026-10-21","base":"AUD","rates":{"AEMO_VIC1_SPOT":119.222},"dates":{"AEMO_VIC1_SPOT":"2026-10-21"},"currencies":{"AEMO_VIC1_SPOT":"AUD"},"base_filter_note":null}
What to read:
- success: boolean to check the request worked.
- date: the server’s canonical date for this snapshot.
- base: the base currency context for the snapshot (AUD here).
- rates.AEMO_VIC1_SPOT: the numeric price for Victoria Electricity for the reported date.
- dates.AEMO_VIC1_SPOT: the effective date for that price.
- currencies.AEMO_VIC1_SPOT: currency for the symbol (AUD for Victoria).
Store prices with the following triple to avoid ambiguity: (value, currency, unit). For AEMO_VIC1_SPOT that is (119.222, AUD, AUD/MWh). The currency is AUD and the engineering unit is AUD/MWh; keep both, because your downstream logic might need currency conversions or MWh-to-kWh transforms.
Python example: query, validate, and persist the Victoria series
This Python snippet calls the same endpoint and extracts the fields you will need to load into a data store. It also includes defensive checks for currency and dates.
import os
import sys
import json
import urllib.parse
import urllib.request
from datetime import date
API_URL = "https://energy-api.com/api/v1/timeseries"
def fetch_victoria_spot(start, end, api_key):
params = {
"start": start,
"end": end,
"symbols": "AEMO_VIC1_SPOT",
"api_key": api_key
}
url = API_URL + "?" + urllib.parse.urlencode(params)
with urllib.request.urlopen(url) as resp:
raw = resp.read().decode("utf-8")
data = json.loads(raw)
if not data.get("success"):
raise RuntimeError("Energy API returned success=false")
# Validate presence of required fields
rates = data.get("rates", {})
dates = data.get("dates", {})
currencies = data.get("currencies", {})
if "AEMO_VIC1_SPOT" not in rates:
raise KeyError("Missing AEMO_VIC1_SPOT in rates")
if "AEMO_VIC1_SPOT" not in dates:
raise KeyError("Missing AEMO_VIC1_SPOT in dates")
if "AEMO_VIC1_SPOT" not in currencies:
raise KeyError("Missing AEMO_VIC1_SPOT in currencies")
# Extract and normalize
value = float(rates["AEMO_VIC1_SPOT"])
obs_date = dates["AEMO_VIC1_SPOT"]
currency = currencies["AEMO_VIC1_SPOT"]
base = data.get("base")
# Sanity checks
if currency != "AUD":
raise ValueError(f"Unexpected currency {currency} for AEMO_VIC1_SPOT")
if base not in ("AUD", None):
# Base is a context for the snapshot. Accept AUD or None.
raise ValueError(f"Unexpected base {base}")
# Persist-worthy record for a warehouse table
record = {
"symbol": "AEMO_VIC1_SPOT",
"observation_date": obs_date, # YYYY-MM-DD
"value": value, # numeric
"currency": currency, # "AUD"
"unit": "AUD/MWh", # engineering unit
"snapshot_base": base # e.g., "AUD"
}
return data, record
if __name__ == "__main__":
api_key = os.environ.get("ENERGY_API_KEY", "YOUR_API_KEY")
start = "2026-01-01"
end = "2026-03-31"
data, record = fetch_victoria_spot(start, end, api_key)
print(json.dumps(record, indent=2))
Three complete JSON response examples you can paste into tests
Use these when writing parsers, fixtures, or unit tests. They are provided verbatim from the official and real samples.
Example A: Official sample response (kept exactly as provided)
{
"success": true,
"date": "2026-10-23",
"base": "EUR",
"rates": {
"OMIE_ES_DA": 110.0906
},
"dates": {
"OMIE_ES_DA": "2026-10-23"
},
"currencies": {
"OMIE_ES_DA": "EUR"
},
"base_filter_note": null
}
Example B: Real Victoria Electricity response (use for AUD parsing and value extraction)
{"success":true,"date":"2026-10-21","base":"AUD","rates":{"AEMO_VIC1_SPOT":119.222},"dates":{"AEMO_VIC1_SPOT":"2026-10-21"},"currencies":{"AEMO_VIC1_SPOT":"AUD"},"base_filter_note":null}
Example C: Same real response for a second parser test case (currency and keys validation)
{"success":true,"date":"2026-10-21","base":"AUD","rates":{"AEMO_VIC1_SPOT":119.222},"dates":{"AEMO_VIC1_SPOT":"2026-10-21"},"currencies":{"AEMO_VIC1_SPOT":"AUD"},"base_filter_note":null}
Working with time windows, caching, and non-trading days
Energy markets publish prices with different cadences. For backfills, request wider windows and collapse or resample client-side as needed. The timeseries endpoint uses inclusive start and end dates, so your daily ETL can request the last N days without missing boundaries.
- Time windows: For monthly backfills, use a month’s first and last dates and request AEMO_VIC1_SPOT in one call.
- Timezone: Treat dates as market calendar dates. Store them as plain YYYY-MM-DD; do not append local time unless your warehouse requires timestamps.
- Non-trading days: If a market does not publish on certain days, you may see gaps. Handle missing dates gracefully when computing rolling metrics.
- Caching: Cache stable historical windows server-side in your app to avoid re-fetching. For a daily job, only refresh the most recent 1–3 days to catch corrections.
- Idempotency: If you rerun a day’s ingestion, upsert by (symbol, date) to avoid duplicates.
Robust extraction: mapping symbol to value, date, and currency
The response is keyed by symbol across multiple maps. In production code, write one helper that safely reads the trio from rates, dates, and currencies. The maps are single-keyed in this guide (only AEMO_VIC1_SPOT), but structuring your code for multiple symbols allows you to expand later without changing parsing logic.
- Read the price from rates.AEMO_VIC1_SPOT as a float.
- Read the effective date from dates.AEMO_VIC1_SPOT; store it as a date string or a date type.
- Read the currency from currencies.AEMO_VIC1_SPOT and check it equals AUD for Victoria Electricity.
Always persist the engineering unit AUD/MWh alongside the numeric value so your models remain explicit about what a “price” means physically and financially.
Validation checks that catch silent data bugs
Add lightweight assertions to each run. They will save hours of debugging later:
- success must be true; otherwise, log and alert.
- rates must contain AEMO_VIC1_SPOT; treat a missing key as a data gap.
- currency must equal AUD for AEMO_VIC1_SPOT. If not, alarm before persisting.
- date fields must be valid ISO dates and not in the far future relative to your system clock.
- If you keep a daily table, enforce uniqueness on (symbol, observation_date).
End-to-end workflow for historical Victoria Electricity prices
1) Fetch a bounded window
Use the curl above to confirm connectivity for the window you need (e.g., a quarterly backfill). In a job runner, call the same endpoint with your start and end. For large horizons, break into calendar quarters to keep responses easy to inspect and retry.
2) Parse and normalize
Map each observation into columns: symbol, observation_date, value, currency, unit. Avoid storing only value; keep the symbol to guard against accidental cross-joins with other series.
3) Store and index
In a relational store, index on (symbol, observation_date). In a columnar lake, partition by symbol and year for efficient reads. This speeds up rolling metrics like weekly means or volatility bands.
4) Compute model inputs
From the normalized table, derive features such as 7-day mean, month-to-date average, or deviations from a seasonal baseline. Because this series is AUD/MWh, currency conversion to a portfolio base currency should use FX layers outside this guide; keep original AUD values intact.
Common pitfalls and how to avoid them
- Confusing currency with unit: Currency is AUD; the engineering unit is AUD/MWh. Store both.
- Assuming continuous coverage: Handle missing dates without imputing unless your model requires it.
- Overwriting historical corrections: Prefer upserts so late corrections replace older values cleanly.
- Mixing symbols in the same parse path: Always read by explicit symbol keys to avoid cross-series contamination.
- Hardcoding dates: Derive rolling windows from your job’s runtime to simplify scheduling.
Reference: official request and response blocks (verbatim)
Keep these for doc parity and quick smoke tests.
cURL:
curl -G "https://energy-api.com/api/v1/timeseries" --data-urlencode "start=2026-01-01" --data-urlencode "end=2026-03-31" --data-urlencode "symbols=AEMO_VIC1_SPOT" --data-urlencode "api_key=YOUR_API_KEY"
JSON:
{
"success": true,
"date": "2026-10-23",
"base": "EUR",
"rates": {
"OMIE_ES_DA": 110.0906
},
"dates": {
"OMIE_ES_DA": "2026-10-23"
},
"currencies": {
"OMIE_ES_DA": "EUR"
},
"base_filter_note": null
}
FAQ
How do I authenticate?
Pass your key with the api_key query parameter. Use YOUR_API_KEY in local scripts and environment variables in production. Do not place secrets in source control.
What unit do the Victoria Electricity prices use?
AUD/MWh. Also verify currencies.AEMO_VIC1_SPOT equals AUD in the response.
How should I handle missing dates?
Treat them as gaps. For analytics that require continuity, resample with explicit rules (e.g., forward-fill for visualization only). Do not assume all dates exist.
Can I query multiple symbols?
Yes, symbols accepts a comma-separated list. In this guide we only use AEMO_VIC1_SPOT. Parse each symbol’s value/date/currency by its own key.
Where are the full parameter details?
See the official Documentation for complete parameter behavior and additional examples.
Set up your key and get your first Victoria Electricity backfill running in minutes. Create your account here: Register.
Ready to get started?
Get your API key and start querying energy commodity prices in minutes.
Get API Key