New South Wales Electricity Spot Price

New South Wales Electricity Spot Price

Energy risk and finance teams in Australia often need a dependable, programmatic way to fetch the New South Wales (NSW) electricity spot price for P&L attribution, hedge checks, exposure dashboards, and automated settlements. By the end of this post, you will be able to query the live NSW spot price via a simple HTTP GET, parse the numeric rate with PHP and Python/JavaScript, handle currency and units correctly (AUD/MWh), and integrate the value safely into finance workflows.

What you will build: a production-grade fetch for NSW spot in AUD/MWh

This guide focuses on the Energy API symbol “New South Wales Electricity” with the code AEMO_NSW1_SPOT. You will:

Illustration: New South Wales Electricity Spot Price
  • Call GET /api/v1/latest with the required symbols and api_key parameters.
  • Read the rates, dates, and currencies objects for AEMO_NSW1_SPOT.
  • Treat results as finance-grade inputs: numeric parsing, date alignment, and currency checks.
  • Integrate with PHP first (primary example), plus Python/JavaScript for quick automation.

Before coding, register for an API key and review the docs:

Key facts for finance integrations

  • Symbol name: New South Wales Electricity
  • Symbol code: AEMO_NSW1_SPOT
  • Unit: AUD/MWh
  • Authentication: api_key query parameter (use YOUR_API_KEY as the placeholder)
  • Reading fields: use rates.AEMO_NSW1_SPOT, dates.AEMO_NSW1_SPOT, currencies.AEMO_NSW1_SPOT
  • Base currency: base may be MIXED on multi-symbol responses. Always consult currencies.AEMO_NSW1_SPOT for the per-symbol unit currency (AUD here).
  • Plans: Starter $19.99/mo with a 7-day trial / 50 calls.
  • When requesting symbols that include TTF_GAS or EUA_CO2, do not pass base=USD.

Endpoint and request construction

Use the latest endpoint with a GET request and URL-encoded query parameters:

  • Endpoint: https://energy-api.com/api/v1/latest
  • HTTP method: GET (with query parameters)
  • Required params: symbols, api_key

For a single NSW spot price pull, your symbols parameter is AEMO_NSW1_SPOT. Authentication uses the api_key query parameter. Always URL-encode values.

Official cURL samples

Use these exact commands when testing the API. They are copy-pasteable and match the documentation.

Direct NSW spot price (AEMO_NSW1_SPOT)

curl -G "https://energy-api.com/api/v1/latest" --data-urlencode "symbols=AEMO_NSW1_SPOT" --data-urlencode "api_key=YOUR_API_KEY"

Official sample from the docs (verbatim)

curl -G "https://energy-api.com/api/v1/latest" --data-urlencode "symbols=AEMO_NSW1_SPOT" --data-urlencode "api_key=YOUR_API_KEY"

Understanding response fields with real examples

Below are complete JSON examples to help you wire the fields precisely. Copy them into tests or mocks as needed and map the exact keys for finance-grade parsing.

Official JSON sample (verbatim from the docs)

{
"success": true,
"date": "2026-11-12",
"base": "EUR",
"rates": {
"OMIE_ES_DA": 116.1602
},
"dates": {
"OMIE_ES_DA": "2026-11-12"
},
"currencies": {
"OMIE_ES_DA": "EUR"
},
"base_filter_note": null,
"missing_symbols": null
}

Notes for NSW readers: The keys you will bind in your code are the same structural positions, but with your symbol AEMO_NSW1_SPOT. The finance-relevant fields are:

  • rates.SYMBOL: numeric price (float/decimal). Treat as AUD/MWh for AEMO_NSW1_SPOT.
  • dates.SYMBOL: ISO date for the value you fetched. Align it with your valuation or settlement date.
  • currencies.SYMBOL: per-symbol currency. For AEMO_NSW1_SPOT, this will be AUD.
  • base: may differ on multi-symbol requests; rely on per-symbol currencies.* for correctness.

Real API response for AEMO_NSW1_SPOT (use these values exactly)

{"success":true,"date":"2026-11-11","base":"AUD","rates":{"AEMO_NSW1_SPOT":104.1618},"dates":{"AEMO_NSW1_SPOT":"2026-11-11"},"currencies":{"AEMO_NSW1_SPOT":"AUD"},"base_filter_note":null,"missing_symbols":null}

Field usage for finance:

  • rates.AEMO_NSW1_SPOT = 104.1618 → the NSW electricity spot price in AUD/MWh.
  • dates.AEMO_NSW1_SPOT = 2026-11-11 → the pricing date to tag in your ledger or risk store.
  • currencies.AEMO_NSW1_SPOT = AUD → confirms your unit currency for cash conversion logic.
  • base = AUD → relevant at the response page level; still prefer per-symbol currencies for multi-symbol safety.

Second real example (same symbol and values for deterministic binding tests)

{"success":true,"date":"2026-11-11","base":"AUD","rates":{"AEMO_NSW1_SPOT":104.1618},"dates":{"AEMO_NSW1_SPOT":"2026-11-11"},"currencies":{"AEMO_NSW1_SPOT":"AUD"},"base_filter_note":null,"missing_symbols":null}

Tip: Reusing the exact same JSON in tests ensures your parser handles nested maps consistently under production-like keys for rates, dates, and currencies.

PHP: end-to-end guide for AEMO_NSW1_SPOT (primary)

The following PHP snippet performs a GET request with query parameters, decodes JSON, and extracts the NSW spot price, its currency, and date for downstream finance use. It ensures strict key checks and safe numeric handling.

<?php
$endpoint = 'https://energy-api.com/api/v1/latest';
$params = [
'symbols' => 'AEMO_NSW1_SPOT',
'api_key' => 'YOUR_API_KEY'
];

// Build query string safely
$query = http_build_query($params);
$url = $endpoint . '?' . $query;

// Basic cURL GET
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
]);

$response = curl_exec($ch);
if ($response === false) {
throw new RuntimeException('HTTP error: ' . curl_error($ch));
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// Check HTTP and decode JSON
if ($httpCode < 200 || $httpCode >= 300) {
throw new RuntimeException('Unexpected HTTP status code: ' . $httpCode);
}

$data = json_decode($response, true, 512, JSON_THROW_ON_ERROR);

// Validate structure
if (!isset($data['success']) || $data['success'] !== true) {
throw new RuntimeException('API reported unsuccessful response');
}

$symbol = 'AEMO_NSW1_SPOT';

// Extract fields with strict checks
if (!isset($data['rates'][$symbol], $data['dates'][$symbol], $data['currencies'][$symbol])) {
throw new RuntimeException('Missing expected fields for ' . $symbol);
}

// Finance-grade parsing
$price = (float)$data['rates'][$symbol]; // AUD/MWh
$priceDate = $data['dates'][$symbol]; // 'YYYY-MM-DD'
$ccy = $data['currencies'][$symbol]; // 'AUD'

// Optional sanity checks
if ($ccy !== 'AUD') {
throw new RuntimeException('Unexpected currency for ' . $symbol . ': ' . $ccy);
}
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $priceDate)) {
throw new RuntimeException('Invalid price date format: ' . $priceDate);
}

// Use the data: example payload for your ledger or risk store
$result = [
'symbol' => $symbol,
'value' => $price, // AUD/MWh
'currency' => $ccy,
'valuation_date' => $priceDate,
];

echo json_encode($result, JSON_PRETTY_PRINT) . PHP_EOL;

Integration notes:

  • Use a decimal-safe type for storage (e.g., DECIMAL(16,6)) to avoid float precision issues.
  • Align valuation_date with your finance calendar and P&L timing.
  • Log the full response for auditability; include request URL and HTTP code.

JavaScript and Python quick calls

JavaScript (Node.js, using fetch)

import fetch from 'node-fetch';

const endpoint = 'https://energy-api.com/api/v1/latest';
const params = new URLSearchParams({
symbols: 'AEMO_NSW1_SPOT',
api_key: 'YOUR_API_KEY'
});
const url = `${endpoint}?${params.toString()}`;

const res = await fetch(url, { method: 'GET', timeout: 20000 });
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
const data = await res.json();

if (data.success !== true) {
throw new Error('API returned unsuccessful response');
}

const sym = 'AEMO_NSW1_SPOT';
const price = Number(data.rates?.[sym]);
const dateFor = data.dates?.[sym];
const ccy = data.currencies?.[sym];

if (!Number.isFinite(price)) {
throw new Error('Invalid price number');
}
if (ccy !== 'AUD') {
throw new Error(`Unexpected currency ${ccy}`);
}

console.log({ symbol: sym, price, unit: 'AUD/MWh', date: dateFor, currency: ccy });

Python (requests)

import requests

endpoint = "https://energy-api.com/api/v1/latest"
params = {
"symbols": "AEMO_NSW1_SPOT",
"api_key": "YOUR_API_KEY",
}

resp = requests.get(endpoint, params=params, timeout=20)
resp.raise_for_status()
data = resp.json()

if not data.get("success", False):
raise RuntimeError("API unsuccessful")

sym = "AEMO_NSW1_SPOT"

try:
price = float(data["rates"][sym]) # AUD/MWh
price_date = data["dates"][sym] # YYYY-MM-DD
ccy = data["currencies"][sym] # AUD
except KeyError as e:
raise KeyError(f"Missing key in response: {e}")

if ccy != "AUD":
raise ValueError(f"Unexpected currency: {ccy}")

print({
"symbol": sym,
"value": price,
"currency": ccy,
"valuation_date": price_date,
})

Currency, units, and base handling

For AEMO_NSW1_SPOT, the unit is AUD/MWh. That is your finance unit for settlement- and P&L-oriented calculations. Always read currencies.AEMO_NSW1_SPOT to validate currency; do not assume the top-level base applies uniformly across symbols. Multi-symbol requests may have base=MIXED, so bind to per-symbol currencies.* fields for correct unit tagging in your ledgers.

If you later add additional symbols such as TTF_GAS or EUA_CO2, do not pass base=USD in the same request. Keep your NSW queries simple (symbols=AEMO_NSW1_SPOT) unless you’re normalizing multi-commodity dashboards and you’ve verified currency strategies against the per-symbol currencies map.

Practical operations: dates, caching, and reliability

Date fields are ISO (YYYY-MM-DD). Use dates.AEMO_NSW1_SPOT to tag the valuation date in P&L or risk cubes. This avoids mismatches when comparing across ledgers or rolling up daily exposures.

Caching: if your finance UI refreshes frequently, cache the last successful response in memory or a key-value store and display a timestamp. This prevents rapid re-queries and helps remain within trial limits (7 days / 50 calls on Starter trial). For back-office batch runs, snapshot the entire response body to object storage for audit and replay.

Timeouts and retries: set client timeouts to around 20 seconds and consider a simple retry with jitter for transient network errors. Always check success, and gracefully handle missing_symbols if present (null in the examples above).

Validation checklist before shipping

  • Authentication via api_key query parameter is present and URL-encoded.
  • Symbol is exactly AEMO_NSW1_SPOT for NSW spot; no substitutions.
  • Read rates.AEMO_NSW1_SPOT (float), dates.AEMO_NSW1_SPOT (YYYY-MM-DD), currencies.AEMO_NSW1_SPOT (AUD).
  • Persist numeric values using a fixed-precision decimal type to prevent rounding drift.
  • Log full response JSON alongside the computed P&L or exposure for traceability.
  • Do not include base=USD if you also add TTF_GAS or EUA_CO2 in future queries.

Field-by-field explanation (concise)

  • success: boolean indicating if the request was processed successfully.
  • date: response-level date marker; do not rely on it for all symbols if you query many—use dates.SYMBOL.
  • base: response-level base; may be MIXED; always cross-check currencies.SYMBOL.
  • rates.AEMO_NSW1_SPOT: the NSW electricity spot price (AUD/MWh) as float/decimal.
  • dates.AEMO_NSW1_SPOT: the specific date to attribute the rate to.
  • currencies.AEMO_NSW1_SPOT: ‘AUD’ for this symbol.
  • base_filter_note: can be null; check if present for filtering hints when expanding your symbol list.
  • missing_symbols: null or list; handle gracefully if you pass extra symbols.

Troubleshooting and common pitfalls

  • Symbol typos: any deviation from AEMO_NSW1_SPOT will yield missing_symbols or zero results.
  • Currency assumptions: even if base shows AUD in your current tests, rely on currencies.AEMO_NSW1_SPOT.
  • Number parsing: ensure locale-independent parsing (e.g., dot decimal separator) before posting to finance systems.
  • Batch alignment: if your P&L or settlements run at fixed cutoffs, align to dates.AEMO_NSW1_SPOT and keep a snapshot.

Appendix: more response examples

The following is the same real NSW example once more for deterministic testing across environments.

{"success":true,"date":"2026-11-11","base":"AUD","rates":{"AEMO_NSW1_SPOT":104.1618},"dates":{"AEMO_NSW1_SPOT":"2026-11-11"},"currencies":{"AEMO_NSW1_SPOT":"AUD"},"base_filter_note":null,"missing_symbols":null}

FAQ

Q: What unit is the NSW spot price returned in?
A: AUD per MWh. Read currencies.AEMO_NSW1_SPOT to validate currency and treat rates.AEMO_NSW1_SPOT as the numeric value.

Q: Which fields should I persist for finance auditability?
A: Persist the full JSON response, plus extracted fields: symbol (AEMO_NSW1_SPOT), price, currency (AUD), and dates.AEMO_NSW1_SPOT as valuation_date.

Q: Can I query multiple symbols at once?
A: Yes, pass a comma-separated list to symbols. However, base may be MIXED; always rely on per-symbol currencies.*. Do not pass base=USD if your list includes TTF_GAS or EUA_CO2.

Q: How do I authenticate?
A: Include api_key=YOUR_API_KEY as a query parameter. Keep your key secure and out of client-side code that ships to browsers.

Q: How do I minimize call volume during a 7-day trial?
A: Cache successful responses for your display layer and schedule batch snapshots at fixed times aligned to your finance processes.

Ready to integrate the NSW spot price into your finance stack? Create your API key and start coding in minutes: Register. For parameter details and response semantics, see the Documentation.

Ready to get started?

Get your API key and start querying energy commodity prices in minutes.

Get API Key

Related posts