PJM West Day-Ahead Price API

PJM West Day-Ahead Price API

You need a dependable way to fetch the latest PJM West Day-Ahead power price for finance workflows—pricing models, PnL explain, or trading dashboards—and by the end of this guide you will know exactly how to call the Energy API, interpret the response fields for PJM_WEST_DA, and harden your integration with retries, caching, and error handling.

What the PJM West Day-Ahead symbol represents

PJM West Day-Ahead (code: PJM_WEST_DA) is a standardized price series representing day-ahead cleared power for the PJM West hub. The unit is USD/MWh. This makes it straightforward to use in finance applications that value power exposures, compare regional spreads, or reconcile settlement estimates against market quotes.

Illustration: PJM West Day-Ahead Price API
  • Symbol name: PJM West Day-Ahead
  • Symbol code: PJM_WEST_DA
  • Unit: USD/MWh
  • No MCP host is required and there is no MCP field to parse in this API.

Endpoint, authentication, and parameters

You will query a single endpoint for latest prices:

  • HTTP Method: GET
  • URL: https://energy-api.com/api/v1/latest
  • Query parameters:
    • symbols: one or more comma-separated codes (use PJM_WEST_DA for this guide)
    • api_key: your API key as a query parameter (use the literal placeholder YOUR_API_KEY in examples)

Do not pass any base parameter for this use case. Specifically, do not pass base=USD when you also need TTF_GAS or EUA_CO2; base may be MIXED and it is acceptable to read currency per symbol from the currencies map for multi-commodity baskets. For PJM_WEST_DA, you will read its unit and currency directly from the response fields.

Quickstart: one-liner cURL for PJM_WEST_DA

Copy, paste, and run the following cURL to request the latest PJM West Day-Ahead price. Replace YOUR_API_KEY with your actual key when you’re ready to run in your environment.

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

Official response schema example (from live source)

The API returns a consistent envelope with top-level fields like success, date, base, and nested maps keyed by symbol code. The following official sample illustrates that schema. Note that the symbol shown here (OMIE_ES_DA) is for illustration of structure only; your application should continue using PJM_WEST_DA.

{
"success": true,
"date": "2026-10-07",
"base": "EUR",
"rates": {
"OMIE_ES_DA": 182.4049
},
"dates": {
"OMIE_ES_DA": "2026-10-07"
},
"currencies": {
"OMIE_ES_DA": "EUR"
},
"base_filter_note": null
}

Field usage you’ll rely on:

  • success: boolean indicating if rate data is available.
  • date: server’s reference date for the snapshot (not necessarily the trading session).
  • rates[SYMBOL]: numeric latest price (for PJM_WEST_DA, this is a USD/MWh price).
  • dates[SYMBOL]: ISO date for the symbol’s quote timestamp lineage.
  • currencies[SYMBOL]: currency code for the symbol’s price (for PJM_WEST_DA, expect USD with the unit USD/MWh).
  • base: may be MIXED for baskets; do not rely on base for single-symbol PJM_WEST_DA reads—use currencies[SYMBOL] and the known unit.

Real API response for PJM_WEST_DA (live call did not succeed)

The most recent live call returned an error envelope. Use this exact output to build your error handling. Do not assume a successful payload is always present.

{"success":false,"error":"No rate data available for the requested symbols."}

Behavior to implement:

  • Check success first. If false, log the error string and apply a retry or fallback.
  • Do not attempt to read rates, dates, or currencies when success is false.
  • Consider a limited backoff and caching of the last known value if your application permits it.

Error envelope upon immediate retry (example)

If you retry too quickly, you may continue to receive the same envelope. Your client should degrade gracefully and avoid tight retry loops.

{"success":false,"error":"No rate data available for the requested symbols."}

Schema reference example repeated for validation tests

When constructing unit tests, use the official schema example below to verify that your parser correctly reads the maps (rates, dates, currencies) by symbol key. Again, this sample uses a different symbol purely to validate structure.

{
"success": true,
"date": "2026-10-07",
"base": "EUR",
"rates": {
"OMIE_ES_DA": 182.4049
},
"dates": {
"OMIE_ES_DA": "2026-10-07"
},
"currencies": {
"OMIE_ES_DA": "EUR"
},
"base_filter_note": null
}

Python example: fetching PJM_WEST_DA and handling the error envelope

This Python script calls the same endpoint, checks success, and shows where you would read the PJM_WEST_DA fields. Keep the same URL and parameters; the API uses the api_key query parameter for authentication.

import os
import time
import requests

API_URL = "https://energy-api.com/api/v1/latest"
API_KEY = os.getenv("ENERGY_API_KEY", "YOUR_API_KEY") # replace in production
SYMBOL = "PJM_WEST_DA"

def fetch_latest(symbol: str):
params = {
"symbols": symbol,
"api_key": API_KEY
}
r = requests.get(API_URL, params=params, timeout=10)
r.raise_for_status()
return r.json()

def get_pjm_west_da():
# Basic retry: 3 attempts with incremental backoff
for attempt in range(3):
data = fetch_latest(SYMBOL)
if data.get("success") is True:
# Read by symbol key
price = data["rates"].get(SYMBOL)
quote_date = data["dates"].get(SYMBOL)
currency = data["currencies"].get(SYMBOL)
# For PJM_WEST_DA, unit is USD/MWh
return {
"symbol": SYMBOL,
"price": price,
"currency": currency,
"unit": "USD/MWh",
"quote_date": quote_date,
"envelope_date": data.get("date"),
"base": data.get("base")
}
else:
# Log and back off before retry
err = data.get("error", "Unknown error")
print(f"Attempt {attempt+1}: {err}")
if attempt < 2:
time.sleep(2 * (attempt + 1))
return None

if __name__ == "__main__":
result = get_pjm_west_da()
if result is None:
print("PJM_WEST_DA not available at this time.")
else:
print(f"{result['symbol']} {result['price']} {result['currency']} ({result['unit']}) as of {result['quote_date']}")

JavaScript example: browser-safe fetch with defensive parsing

This snippet uses the Fetch API. For browser apps, never hardcode private keys; proxy the request via your backend. For demonstration, we include the query parameter explicitly with a placeholder value.

const API_URL = "https://energy-api.com/api/v1/latest";
const API_KEY = "YOUR_API_KEY"; // replace via secure server-side injection
const SYMBOL = "PJM_WEST_DA";

async function fetchPjmWestDa() {
const url = new URL(API_URL);
url.searchParams.set("symbols", SYMBOL);
url.searchParams.set("api_key", API_KEY);

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

if (data.success !== true) {
const msg = data.error || "No rate data";
return { ok: false, error: msg };
}

const price = data.rates?.[SYMBOL];
const quoteDate = data.dates?.[SYMBOL];
const currency = data.currencies?.[SYMBOL];
return {
ok: true,
symbol: SYMBOL,
price,
currency,
unit: "USD/MWh",
quoteDate,
envelopeDate: data.date,
base: data.base
};
}

fetchPjmWestDa()
.then(result => {
if (!result.ok) {
console.warn("PJM_WEST_DA unavailable:", result.error);
return;
}
console.log(`${result.symbol}: ${result.price} ${result.currency} (${result.unit}) on ${result.quoteDate}`);
})
.catch(err => console.error("Request failed:", err));

Field semantics you will use in finance integrations

For PJM_WEST_DA, read the following fields when success is true:

  • rates.PJM_WEST_DA: latest day-ahead price for the PJM West hub.
  • dates.PJM_WEST_DA: ISO date string for the specific symbol’s quote lineage.
  • currencies.PJM_WEST_DA: the currency of the numeric rate (expect USD for PJM_WEST_DA).

Unit handling: The symbol’s unit is USD/MWh. For cashflow or valuation pipelines, multiply MWh volume by rates.PJM_WEST_DA, taking care to align delivery periods with your timeseries frequency.

Base field: base may be MIXED across portfolios. Do not pass a base parameter for PJM_WEST_DA-only requests. When building cross-commodity baskets (e.g., adding TTF_GAS or EUA_CO2), rely on currencies[SYMBOL] per series and convert explicitly in your code if required.

Timestamps and timezone: The envelope date is a server-side snapshot date. The dates[SYMBOL] value anchors the specific symbol’s quote date; your downstream logic should use dates[SYMBOL] when deciding staleness, with a local cache TTL that fits your workflow.

Live error handling: replicate the envelope in tests

Your CI should test for both success=true and success=false. The following error JSON is the exact envelope you might receive during outages or when data is not yet available for the requested symbol.

{"success":false,"error":"No rate data available for the requested symbols."}

Suggested strategies:

  • Cache last known good price for short windows to keep UIs responsive.
  • Flag gaps with a clear status in any PnL or risk output when price is missing.
  • Alert only after a threshold (e.g., 5 consecutive failures) to avoid noise.

Performance, caching, and call budgeting

Starter plan is $19.99/mo with a 7-day trial that includes 50 calls. Treat latest quotes as edge-cached artifacts in your application:

  • Batch symbols when applicable by comma-separating values in symbols to reduce round-trips (for this article we focus on a single symbol: PJM_WEST_DA).
  • Introduce a minimal cache in your backend keyed by symbol to smooth over short-lived outages.
  • Backoff on error to preserve trial call quota and avoid hot loops (e.g., 2s, 4s, 8s).

Operational checklist for a production finance workflow

  • Authentication: Use the api_key query parameter; never embed the real key in client-side code.
  • Validation: Always check the success flag before dereferencing rates, dates, or currencies.
  • Units: Treat PJM_WEST_DA as USD/MWh; persist the unit alongside stored quotes for auditability.
  • Base: Do not rely on base for valuation; prefer currencies[SYMBOL] and an explicit conversion step when mixing series.
  • Observability: Log the full response envelope (minus secrets) when success is false to accelerate incident diagnosis.

FAQs

How do I authenticate my requests?

Pass your key as a query parameter named api_key. Use the literal placeholder YOUR_API_KEY in samples and inject the real secret from your server at runtime.

Which fields should I read for the PJM West Day-Ahead price?

Read rates.PJM_WEST_DA for the numeric value, dates.PJM_WEST_DA for the quote date, and currencies.PJM_WEST_DA for the currency. The unit for PJM_WEST_DA is USD/MWh.

Should I pass a base currency?

No. For PJM_WEST_DA, do not pass base=USD. In multi-commodity baskets (e.g., including TTF_GAS or EUA_CO2), base may be MIXED; handle currency per symbol via currencies[SYMBOL].

What should I do when the API returns success=false?

Use the error string for logging, backoff before retrying, and fall back to cached data if your workflow allows. Do not attempt to read rates or dates when success is false.

How many calls can I make during the trial?

The trial is 7 days and includes 50 calls. Implement caching and backoff to stay within this budget while you integrate.

Get access and ship your PJM West Day-Ahead integration

Start with a trial key, wire up the single latest endpoint, and use the success flag to drive your cache and retry logic. When you’re ready, create your account via Register and review field-by-field details in the Documentation.

Ready to get started?

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

Get API Key

Related posts