# CAISO Wholesale Electricity LMP Feed (`kevinserver24/caiso-ercot-lmp`) Actor

Normalized day-ahead and real-time Locational Marginal Price (LMP) records for CAISO pricing nodes, read live from CAISO OASIS's public market data API and split into energy, congestion and loss components. No API key. No field describes a person.

- **URL**: https://apify.com/kevinserver24/caiso-ercot-lmp.md
- **Developed by:** [Kevin](https://apify.com/kevinserver24) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$13.00 / 1,000 lmp record verifieds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## CAISO Wholesale Electricity LMP Feed

Given one or more CAISO pricing nodes, this Actor returns normalized
Locational Marginal Price (LMP) records — day-ahead ("DAM") or real-time
("RTM") — read live from CAISO OASIS, the California ISO's public market
data API, with each price split into its energy, congestion and loss
components.

### Why this is not a five-minute scrape

CAISO's OASIS API answers every query, success or failure, wrapped in a zip
file. A successful query returns a CSV with **one row per price component**
(energy, congestion, loss, and a couple of others this Actor drops by
design) for every node-interval — those rows have to be pivoted into one
clean record per interval, and the naive grouping key (CAISO's own hourly
`OPR_HR` bucket) silently collapses distinct 5-minute real-time intervals
into one record with no error raised. This Actor groups on the interval's
own start timestamp instead, verified against real day-ahead and real-time
captures.

Real-time (RTM) data lives under a **different query name**
(`PRC_INTVL_LMP`) than day-ahead (`PRC_LMP`) — querying RTM with the DAM
query name returns a well-formed "no data" answer, not real rows, and
nothing in the response tells you the query name was wrong.

The answer also **expires by construction**: day-ahead prices post once a
day for the next day; real-time prices change every five minutes. A cached
result from an hour ago is not this hour's price.

### Input

- `nodes` — one or more CAISO pricing node IDs (e.g. `TH_NP15_GEN-APND`,
  `TH_SP15_GEN-APND`).
- `market_run_id` — `DAM` (day-ahead, hourly) or `RTM` (real-time,
  5-minute). Default `DAM`.
- `date` — the operating date to query, UTC `YYYY-MM-DD`. Defaults to
  yesterday, since both markets have settled data for a day that has fully
  elapsed.
- `hour` — optional. Narrows the query to one hour of the operating date.
  Recommended for `RTM`, where a full unbounded day has not been tested.

### Output

One record per (node, market, interval): `iso`, `node_id`, `market_run_id`,
`operating_date`, `operating_hour`, `interval_start_utc`,
`interval_end_utc`, `lmp_usd`, `energy_component_usd`,
`congestion_component_usd`, `loss_component_usd`. No field describes a
person — every field is a grid location, a time interval, or a price.

A node with no data for the requested window (or an unrecognized node ID)
is delivered as one row naming the reason, never billed, never fabricated.

### Data source and attribution

Prices are read from CAISO OASIS (`oasis.caiso.com`), the California ISO's
public market data system — no API key, no login. Used under CAISO's
own terms of use, which permit reuse with attribution: this product credits
the California ISO as the source of all price data.

An independent, unaffiliated tool. Not affiliated with, endorsed by, or
operated by the California ISO (CAISO), ERCOT, or any other grid operator.
It queries CAISO's public OASIS API and republishes the resulting prices in
a normalized form.

# Actor input Schema

## `nodes` (type: `array`):

One CAISO pricing node per line (or comma-separated), e.g. "TH\_NP15\_GEN-APND" or "TH\_SP15\_GEN-APND" (CAISO's own trading-hub identifiers). Each interval-price record CAISO returns for a node is one billable row.

## `market_run_id` (type: `string`):

"DAM" for day-ahead hourly prices, or "RTM" for real-time 5-minute prices.

## `date` (type: `string`):

The CAISO operating date to query. Left blank, defaults to yesterday (UTC) -- both markets have settled, published data for a day that has fully elapsed.

## `hour` (type: `integer`):

Narrows the query to one hour of the operating date. Left blank, the whole day is requested -- proven live for DAM; for RTM a full day has not been tested and may return more data than a single call is expected to carry, so setting an hour is recommended for RTM.

## Actor input object example

```json
{
  "nodes": [
    "TH_NP15_GEN-APND",
    "TH_SP15_GEN-APND"
  ],
  "market_run_id": "DAM"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "nodes": [
        "TH_NP15_GEN-APND",
        "TH_SP15_GEN-APND"
    ],
    "market_run_id": "DAM"
};

// Run the Actor and wait for it to finish
const run = await client.actor("kevinserver24/caiso-ercot-lmp").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "nodes": [
        "TH_NP15_GEN-APND",
        "TH_SP15_GEN-APND",
    ],
    "market_run_id": "DAM",
}

# Run the Actor and wait for it to finish
run = client.actor("kevinserver24/caiso-ercot-lmp").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "nodes": [
    "TH_NP15_GEN-APND",
    "TH_SP15_GEN-APND"
  ],
  "market_run_id": "DAM"
}' |
apify call kevinserver24/caiso-ercot-lmp --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kevinserver24/caiso-ercot-lmp"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tflA8JNiEFgQP3NxW/builds/iA64xaLKKGffG29qk/openapi.json
