⚡ energy¶
Comprehensive U.S. energy data from the Energy Information Administration (EIA) and Mine Safety and Health Administration (MSHA). Covers electricity generation and retail prices, utility operations, power plant inventory, generator capacity changes, fossil fuel production, state energy consumption, natural gas storage, petroleum stocks, crude oil imports, refinery operations, and coal mine production. All state-level tables join with geo.states via state_abbr. EIA API tables use OFFSET pagination against v2 endpoints. Bulk tables (EIA-860, EIA-861, EIA-860M, EIA-814) use TEXT format with transformers that download, extract, and parse XLSX/ZIP archives.
23 datasets · 263 columns
eia_electricity_generation · table¶
EIA API v2 electric power operational data. Monthly electricity generation (thousand MWh), total fuel consumption (MMBtu), fuel consumption for electricity generation (MMBtu), cost per MMBtu, sulfur content, and ash content. Broken down by state, energy source, and sector. One row per state + energy source + sector + year-month. Cross-references geo.states via state_abbr. THIS TABLE CANNOT BE SUMMED NAIVELY — it interleaves rollup rows with the leaf rows they already contain, on all three axes at once, and a SUM that ignores any of them multiplies the answer: (1) energy_source_code mixes leaves with EIA's own rollups — 'ALL', 'FOS', 'REN' and 'NUC' each already total other rows, and even some leaf-looking codes are nested (COL = BIT + SUB + LIG). Use fuel_is_rollup to pick one level. (2) sector_code likewise carries '99' = "All Sectors" alongside the individual sectors it sums; see sector_is_rollup. (3) geo_level mixes 'state', 'division' and 'national' rows — see that column. For a state's annual generation mix, filter geo_level='state' AND sector_code='99', take the ALL/FOS/REN/NUC rows, and SUM across the 12 months — there is no annual sentinel row, so a per-year figure must be summed from months. Selecting a single month's value per category instead mixes different peak months and produces parts that do not add up to the total. The state_energy_mix view does exactly this and is the intended entry point for mix questions.
| Column | Type | Null | Description |
|---|---|---|---|
generation_ |
integer | no | Calendar year of the generation period |
generation_ |
integer | no | Calendar month (1-12) of the generation period |
state_ |
string | yes | 2-letter state abbreviation (e.g., 'CA') |
state_ |
string | yes | Full state name |
geo_ |
string | yes | Geographic granularity of this row's location: 'state' (real state_abbr), 'division' (Census division rollup, e.g. code '90' for Pacific), or 'national' (US total). Distinguishes the 3 location granularities that all share the same underlying EIA location field, to prevent overcounting on a naive SUM across state + division + national rows. |
energy_ |
string | yes | EIA energy source code (e.g., 'COL', 'NG', 'NUC', 'SUN') |
energy_ |
string | yes | Full energy source description |
fuel_ |
boolean | yes | True when energy_source_code is a rollup/aggregate fuel code (e.g. 'COW' aggregates 'COL'/'LIG'/'SUB', 'TSN' aggregates 'SPV'/'DPV') rather than a true leaf-level fuel, so it should be excluded from a naive SUM alongside its constituent codes. |
sector_ |
string | yes | EIA sector code (e.g., '1', '2', '98', '99') |
sector |
string | yes | Sector description (e.g., 'Electric Utility', 'IPP Non-CHP') |
sector_ |
boolean | yes | True when sector_code is a rollup/aggregate sector code (90, 94-99) rather than a true leaf-level sector (1-8), so it should be excluded from a naive SUM alongside its constituent sectors. |
generation_ |
double | yes | Net electricity generation in thousand MWh |
fuel_ |
double | yes | Total fuel consumed in MMBtu (all purposes) |
fuel_ |
double | yes | Fuel consumed for electricity generation in MMBtu |
fuel_ |
double | yes | Fuel cost per MMBtu in dollars |
sulfur_ |
double | yes | Sulfur content percentage of fuel |
ash_ |
double | yes | Ash content percentage of fuel |
eia_electricity_prices · table¶
EIA API v2 retail electricity sales data, fetched at annual frequency (the source URL hardcodes frequency=annual, so price_month exists in the schema but is always null here). Average price (cents/kWh), revenue (million dollars), sales (million kWh), and customer counts by state and sector. One row per state + sector + year. Cross-references geo.states via state_abbr.
| Column | Type | Null | Description |
|---|---|---|---|
price_ |
integer | no | Calendar year |
price_ |
integer | yes | Calendar month (1-12), null for annual aggregates |
state_ |
string | yes | 2-letter state abbreviation (e.g., 'CA') |
state_ |
string | yes | Full state name |
sector_ |
string | yes | EIA customer sector code (e.g., 'RES', 'COM', 'IND', 'TRA', 'ALL') |
sector |
string | yes | Sector description (e.g., 'Residential', 'Commercial', 'Industrial') |
avg_ |
double | yes | Average retail electricity price in cents per kWh |
revenue_ |
double | yes | Total revenue in million dollars |
sales_ |
double | yes | Total electricity sales in million kWh |
customers |
integer | yes | Number of customer accounts |
eia_utility_annual · table¶
EIA Form 861 annual electric utility survey. Covers all electric utilities, retail power marketers, and energy service providers. Fields include entity type, NERC region, service type, customer counts and sales by sector (residential, commercial, industrial, transportation), revenue, peak demand, and net generation. One row per utility + year. The transformer downloads and parses the annual ZIP archive of XLSX files from EIA. Cross-references geo.states via state_abbr. To reach a utility's cross-schema identity FROM another schema rather than by name, join ref.canonical_org_entity on eia_utility_id = utility_id — that table carries one foreign key per source, so the utility's LEI/SEC CIK and its utility_id sit in the same row and the join is exact. Matching utility_name as text finds the wrong entities and misses utilities filing under a differently-worded name.
| Column | Type | Null | Description |
|---|---|---|---|
utility_ |
integer | no | EIA utility identifier |
report_ |
integer | no | Report year |
utility_ |
string | yes | Utility company name |
entity_ |
string | yes | Entity type code (e.g., 'C', 'I', 'M', 'S', 'F', 'G', 'P', 'Q', 'W') |
state_ |
string | yes | 2-letter state abbreviation (e.g., 'CA') |
ba_ |
string | yes | Balancing authority code |
nerc_ |
string | yes | NERC reliability region code |
service_ |
string | yes | Service type (Bundled, Energy, Delivery) |
data_ |
string | yes | Data type indicator |
activity_ |
boolean | yes | Whether utility engages in generation |
activity_ |
boolean | yes | Whether utility engages in transmission |
activity_ |
boolean | yes | Whether utility engages in distribution |
customers_ |
integer | yes | Number of residential customer accounts |
customers_ |
integer | yes | Number of commercial customer accounts |
customers_ |
integer | yes | Number of industrial customer accounts |
customers_ |
integer | yes | Number of transportation customer accounts |
customers_ |
integer | yes | Total number of customer accounts |
sales_ |
double | yes | Electricity sales to residential customers in MWh |
sales_ |
double | yes | Electricity sales to commercial customers in MWh |
sales_ |
double | yes | Electricity sales to industrial customers in MWh |
sales_ |
double | yes | Electricity sales to transportation customers in MWh |
sales_ |
double | yes | Total electricity sales in MWh |
revenue_ |
double | yes | Revenue from residential customers in thousands of dollars |
revenue_ |
double | yes | Revenue from commercial customers in thousands of dollars |
revenue_ |
double | yes | Revenue from industrial customers in thousands of dollars |
revenue_ |
double | yes | Total revenue in thousands of dollars |
summer_ |
double | yes | Summer peak demand in MW |
winter_ |
double | yes | Winter peak demand in MW |
net_ |
double | yes | Net electricity generation in MWh |
eia_service_territory · table¶
EIA-861 utility-to-county service-territory crosswalk. One row per utility + state + county the utility reported serving in that year (a multi-state or multi-county utility has one row per county). Sourced from the "Counties_States" sheet of the Service_Territory file in the same annual EIA-861 ZIP archive that eia_utility_annual downloads (Counties_States covers the 50 states + DC; the sibling Counties_Territories sheet is out of scope, matching this schema's existing 50-states+DC convention). Does not carry a per-county customer count or sales split — EIA-861 does not publish one — so this table is a service-territory membership list, not a weighted allocation; see eia_electricity_demand_by_county for the county-grain demand apportionment built from it. Cross-references geo.state_ref via state_abbr; joins eia_utility_annual via (utility_id, report_year).
| Column | Type | Null | Description |
|---|---|---|---|
utility_ |
integer | no | EIA utility identifier (links to eia_utility_annual) |
report_ |
integer | no | Report year |
utility_ |
string | yes | Utility company name |
short_ |
boolean | yes | Whether the utility filed the EIA-861 short form (less-detailed survey) |
state_ |
string | yes | 2-letter state abbreviation (e.g., 'CA') |
county_ |
string | no | County name as reported by EIA (no 'County'/'Parish'/'Borough' suffix, e.g. 'Vermilion' not 'Vermilion Parish'). Not a FIPS code — join to geo.counties by name prefix match if a county_fips is needed (see eia_electricity_demand_by_county for a worked example). |
eia_power_plants · table¶
EIA Form 860 annual electric generator inventory. One row per generator (plant + generator ID + year), sourced from BOTH the archive's "Operable" sheet and its "Retired and Canceled" sheet (2011 onward; earlier archives carry only an operable-equivalent). A generator therefore has a row in a given report_year's archive whether it was running that year or had already stopped — filter operating_status IN ('RE','CN') to isolate the latter, and read retirement_year for when it actually happened, as distinct from planned_retirement_year (a forecast made while still operating). Includes plant and utility identifiers, geographic location (state, county, city, lat/lon), NERC region, balancing authority, technology, prime mover, energy sources, capacity (nameplate, summer, winter, minimum load), ownership type, and energy storage flag. Transformer downloads and parses the annual ZIP archive from EIA. Cross-references geo.states via state_abbr; joins eia_utility_annual via utility_id.
| Column | Type | Null | Description |
|---|---|---|---|
plant_ |
integer | no | EIA plant identifier |
generator_ |
string | no | Generator identifier within the plant |
report_ |
integer | no | Report year |
plant_ |
string | yes | Plant name |
utility_ |
integer | yes | EIA utility identifier (links to eia_utility_annual) |
utility_ |
string | yes | Utility company name |
state_ |
string | yes | 2-letter state abbreviation (e.g., 'CA') |
county_ |
string | yes | County name |
county_ |
string | yes | 5-digit county FIPS code |
city |
string | yes | City or town name |
latitude |
double | yes | Plant latitude |
longitude |
double | yes | Plant longitude |
nerc_ |
string | yes | NERC reliability region |
balancing_ |
string | yes | Balancing authority code |
balancing_ |
string | yes | Balancing authority name |
primary_ |
integer | yes | Primary purpose NAICS code |
regulatory_ |
string | yes | Regulatory status (e.g., Regulated, Nonutility) |
sector_ |
integer | yes | EIA sector code |
sector |
string | yes | Sector description |
technology |
string | yes | Generation technology (e.g., 'Conventional Steam Coal', 'Onshore Wind Turbine') |
prime_ |
string | yes | Prime mover code (e.g., 'ST', 'GT', 'IC', 'WT', 'PV') |
energy_ |
string | yes | Primary energy source code |
energy_ |
string | yes | Secondary energy source code |
energy_ |
string | yes | Tertiary energy source code |
nameplate_ |
double | yes | Nameplate (installed) capacity in MW |
net_ |
double | yes | Net summer capacity in MW |
net_ |
double | yes | Net winter capacity in MW |
minimum_ |
double | yes | Minimum load in MW |
ownership_ |
string | yes | Ownership type code |
operating_ |
string | yes | Operating status code — OP (operating), SB (standby/backup), OA (out of service, expected back), OS (out of service, not expected back), P/L/T/U/V (various under-construction / permitting stages), RE (retired) or CN (cancelled or postponed). RE and CN only appear on a row sourced from the "Retired and Canceled" sheet (see retirement_year) — a generator that stopped operating simply has no row on the "Operable" sheet in that year's archive rather than switching this code, so its last "Operable" row's status stays whatever it was the year before it disappeared. |
operating_ |
integer | yes | Month generator began commercial operation |
operating_ |
integer | yes | Year generator began commercial operation |
planned_ |
integer | yes | Planned retirement month, as reported by a still-operating generator on the "Operable" sheet — a forecast, not an actual retirement. Once a generator has actually retired this is no longer populated for it; see retirement_month. |
planned_ |
integer | yes | Planned retirement year — see planned_retirement_month. Not populated once a generator has actually retired; see retirement_year. |
retirement_ |
integer | yes | Actual retirement month, from EIA-860's "Retired and Canceled" sheet — only populated on a row whose operating_status is RE or CN. NULL on every "Operable" sheet row, including one whose planned_retirement_year suggests retirement is coming: this field records that a generator DID retire, not that it is expected to. |
retirement_ |
integer | yes | Actual retirement year — see retirement_month. To find when a generator retired, filter operating_status IN ('RE','CN') and read this column, not planned_retirement_year. |
energy_ |
boolean | yes | Whether generator includes energy storage capability |
eia_capacity_changes · table¶
EIA Form 860M generator inventory, one annual snapshot per snapshot_year. Captures planned additions and planned retirements with capacity (nameplate, summer, winter, energy storage). Transformer parses the XLSX directly. Cross-references geo.states via state_abbr; joins eia_power_plants via plant_id. GRAIN — READ BEFORE AGGREGATING: this is a CUMULATIVE SNAPSHOT, not a change log. One row per generator per snapshot_year, so a single addition or retirement event REAPPEARS in every later snapshot it survives into — measured live, additions with change_year 2020-2024 appear in 1 to 6 distinct snapshot_years each. The row count therefore grows every year by construction (25,986 in 2016 to 38,359 in 2025) without any new events. SUMming nameplate_capacity_mw across snapshot_year multiplies every event by the number of snapshots it appears in: for change_type='Addition' and change_year 2020-2024 that is 746,721 MW across 18,688 rows, against 5,236 real generator-years — roughly 3.6x EIA's own published additions of ~40 GW/yr. To total real capacity change, first reduce to one row per (plant_id, generator_id, change_year) — e.g. pick the newest snapshot_year per generator with QUALIFY ROW_NUMBER() OVER (PARTITION BY plant_id, generator_id, change_year ORDER BY snapshot_year DESC) = 1 — and only then aggregate. snapshot_month is NULL on every row: only the December file is ingested, so the column carries no information and must not be used to disambiguate snapshots.
| Column | Type | Null | Description |
|---|---|---|---|
plant_ |
integer | no | EIA plant identifier |
generator_ |
string | no | Generator identifier within the plant |
snapshot_ |
integer | no | Year of the monthly snapshot file |
snapshot_ |
integer | no | Month of the monthly snapshot file (12 for December) |
change_ |
string | no | Type of capacity change (e.g., 'Planned Addition', 'Planned Retirement', 'New Unit') |
change_ |
integer | yes | Year the change is expected to take effect |
change_ |
integer | yes | Month the change is expected to take effect |
plant_ |
string | yes | Plant name |
entity_ |
integer | yes | EIA entity (utility/owner) identifier |
entity_ |
string | yes | Entity name |
state_ |
string | yes | 2-letter state abbreviation (e.g., 'CA') |
county_ |
string | yes | County name |
balancing_ |
string | yes | Balancing authority code |
sector |
string | yes | Sector description |
technology |
string | yes | Generation technology |
energy_ |
string | yes | Primary energy source code |
prime_ |
string | yes | Prime mover code |
nameplate_ |
double | yes | Nameplate capacity in MW |
net_ |
double | yes | Net summer capacity in MW |
net_ |
double | yes | Net winter capacity in MW |
nameplate_ |
double | yes | Nameplate energy capacity in MWh (for storage units) |
eia_fossil_fuel_production · table¶
EIA API v2 petroleum crude oil production by state and month. Source is a single endpoint (petroleum/crd/crpdn); every fuel_type value is 'Crude Oil' or 'ANS Crude Oil'. Natural gas production is not included — the EIA natural gas production summary lives at a separate endpoint (natural-gas/prod/sum) that this table does not fetch; use eia_natural_gas_price for gas market data. One row per EIA area + process + year-month. Cross-references geo.states via state_abbr.
| Column | Type | Null | Description |
|---|---|---|---|
production_ |
integer | no | Calendar year of production |
production_ |
integer | no | Calendar month (1-12) of production |
eia_ |
string | yes | EIA area/region code (may be state abbreviation or PADD code) |
state_ |
string | yes | 2-letter state abbreviation (e.g., 'CA') |
fuel_ |
string | no | Fuel type — 'Crude Oil' or 'ANS Crude Oil' (Alaska North Slope). Never natural gas; this table's single source is the petroleum crude endpoint. |
process_ |
string | yes | EIA process code identifying the production activity |
process_ |
string | yes | Process description |
production_ |
double | yes | Production volume in units specified by production_unit |
production_ |
string | yes | Unit of measure — one of exactly two short codes this table actually stores: MBBL (thousand barrels) or MBBL/D (thousand barrels per day). The spelled-out forms in series_description ("Thousand Barrels", "Thousand Barrels per Day") never appear here and are not valid filter values (D-270) — filtering on the long form silently returns a near-empty result instead of an error. This table is crude oil only; there is no natural-gas production series (see the table comment), so a gas unit like "Million Cubic Feet" never appears either. |
series_ |
string | yes | EIA API v2 series identifier. Composite key built by EIA from the endpoint's facets: area plus process (e.g. the state's crude oil field production series). The human-readable label is in series_description on the same row, and the decoded parts are in eia_area_code, state_abbr, and process_code. This table is long-format: one row per (series_id, year, month). Enumerate with SELECT DISTINCT series_id, series_description. |
series_ |
string | yes | Full series description |
eia_state_energy_consumption · table¶
EIA API v2 State Energy Data System (SEDS). Annual energy consumption, expenditure, and price by state, sector, fuel type, and MSN (energy series code). The MSN code encodes fuel, sector, and metric in a compact 5-character string. The transformer decodes MSN values and maps them to human-readable sector, fuel_type, units, consumption_bbtu, expenditure_million, and price_per_mmbtu columns where applicable. One row per state + MSN + year. Cross-references geo.states via state_abbr.
| Column | Type | Null | Description |
|---|---|---|---|
year |
integer | no | Calendar year (partition column) |
consumption_ |
integer | no | Calendar year |
state_ |
string | yes | 2-letter state abbreviation (e.g., 'CA') |
state_ |
string | yes | Full state name |
msn |
string | no | EIA Mnemonic Series Name (5-char code, e.g., 'TETCB', 'NGRCB') |
sector |
string | yes | Sector decoded from MSN (e.g., 'Residential', 'Commercial', 'Transportation', 'Total') |
fuel_ |
string | yes | Fuel type decoded from MSN (e.g., 'Natural Gas', 'Coal', 'Petroleum') |
value |
double | yes | Raw numeric value from the API response |
units |
string | yes | Units for the value field |
consumption_ |
double | yes | Energy consumption in billion BTU (null if MSN is not a consumption series) |
expenditure_ |
double | yes | Expenditure in million dollars (null if MSN is not an expenditure series) |
price_ |
double | yes | Price per million BTU (null if MSN is not a price series) |
series_ |
string | yes | Full human-readable description of the SEDS series |
eia_natural_gas_storage · table¶
EIA API v2 weekly natural gas underground storage data. Covers working gas, base gas, total gas, injections, and withdrawals by EIA storage region (East, West, Midwest, Mountain, Pacific, South Central, Salt, Non-Salt, National). One row per region + storage type + report date. Useful for gas market signal analysis and year-over-year storage comparison.
| Column | Type | Null | Description |
|---|---|---|---|
year |
integer | no | Calendar year of the report date (partition column) |
report_ |
string | no | Report date in ISO format (YYYY-MM-DD) |
storage_ |
integer | no | Calendar year of the report date |
storage_ |
integer | no | Week number within the year (ISO week) |
eia_ |
string | yes | EIA storage region code (e.g., 'R10', 'R20', 'R30', 'NAT') |
region |
string | yes | Region description (e.g., 'East', 'West', 'National') |
storage_ |
string | yes | Storage type code (e.g., 'SAW' = total working gas, 'SAS' = salt, 'SAN' = non-salt) |
storage_ |
string | yes | Storage type description |
volume_ |
double | yes | Volume in billion cubic feet |
units |
string | yes | Units for volume (typically 'Bcf') |
series_ |
string | yes | EIA series identifier from the NG bulk archive. Encodes the storage region plus the storage measure; the decoded parts are in eia_region_code, region, storage_type_code, and storage_type (working gas, base gas, total gas, injections, withdrawals). This table is long-format: one row per (series_id, report_date), so ALWAYS filter on series_id (or storage_type_code) — the archive carries both regional and lower-48 totals, and mixing them double counts. Volumes are in Bcf. Enumerate with SELECT DISTINCT series_id. |
eia_petroleum_stocks · table¶
EIA API v2 weekly petroleum product stocks. Covers crude oil and refined products (gasoline, distillate, jet fuel, residual fuel, etc.) by PADD district and national totals. One row per area + product + process + report date. Supports supply disruption analysis, seasonal inventory tracking, and refinery margin signals.
| Column | Type | Null | Description |
|---|---|---|---|
report_ |
string | no | Report date in ISO format (YYYY-MM-DD) |
stock_ |
integer | no | Calendar year of the report date |
stock_ |
integer | no | Week number within the year (ISO week) |
eia_ |
string | yes | EIA area code (e.g., 'SAE', 'USA', 'PAD1', 'PAD2') |
padd |
string | yes | PADD district description or 'National' |
product_ |
string | yes | EIA petroleum product code (e.g., 'EPC0', 'EPM0', 'EPD0') |
product |
string | yes | Product description (e.g., 'Crude Oil', 'Finished Motor Gasoline') |
process_ |
string | yes | EIA process code identifying the stock measurement |
process_ |
string | yes | Process description |
stocks_ |
double | yes | Stocks in thousand barrels |
series_ |
string | yes | EIA API v2 series identifier. Composite key encoding area (PADD or U.S.) plus product plus process; the human-readable label is in series_description on the same row, and the decoded parts are in eia_area_code, padd, product_code, and process_code. This table is long-format: one row per (series_id, report_date), so ALWAYS filter on series_id (or product_code plus padd) — national totals and PADD districts coexist here, so summing across series double counts. Stocks are in thousand barrels. Enumerate with SELECT DISTINCT series_id, series_description. |
series_ |
string | yes | Full series description |
eia_natural_gas_price · table¶
EIA API v2 Henry Hub Natural Gas Spot Price (series RNGWHHD), daily, in dollars per million Btu. Full history in one unpartitioned fetch (~7,500 rows since 1997-01-07, paginated via OFFSET). Pairs with eia_natural_gas_storage / weekly_gas_storage_signal to answer inventory-vs-price questions the corpus previously had no price series for at all — only the storage/inventory side existed.
| Column | Type | Null | Description |
|---|---|---|---|
report_ |
string | no | Report date in ISO format (YYYY-MM-DD) |
series_ |
string | yes | EIA API v2 series identifier (RNGWHHD = Henry Hub spot) |
series_ |
string | yes | Full series description |
product |
string | yes | Product description (Natural Gas) |
process_ |
string | yes | Process description (Spot Price) |
value_ |
double | yes | Price in dollars per million Btu |
units |
string | yes | Unit label as published ($/MMBTU) |
eia_crude_oil_imports · table¶
EIA Form 814 monthly crude oil import survey. The transformer iterates all 12 monthly XLSX files for the given year (URL pattern impa{yy}{m}.xlsx where yy is 2-digit year and m is 1-based month digit) and unions them into a single partition. One row per import transaction per month (importer + origin country + entry port + receiving refinery). Includes API gravity, sulfur content, and volume in thousand barrels. Cross-references geo.states via state_abbr (refinery state).
| Column | Type | Null | Description |
|---|---|---|---|
rpt_ |
string | no | Reporting period in YYYYMM format |
import_ |
integer | no | Import year |
import_ |
integer | no | Import month (1-12) |
importer_ |
string | no | Name of the importing company |
origin_ |
string | yes | Country of origin name |
origin_ |
integer | no | EIA country code for the origin country |
entry_ |
string | yes | PADD district code for the entry port |
entry_ |
string | yes | Entry port city name |
entry_ |
integer | yes | PADD district number of the entry port |
dest_ |
integer | yes | PADD district number of the destination refinery |
receiving_ |
string | yes | Company receiving the crude at the destination |
refinery_ |
integer | no | EIA refinery site identifier |
refinery_ |
string | yes | Refinery site name |
refinery_ |
string | yes | 2-letter state abbreviation of the receiving refinery |
api_ |
double | yes | API gravity of the imported crude |
sulfur_ |
double | yes | Sulfur content as a percentage by weight |
volume_ |
integer | yes | Volume imported in thousand barrels |
eia_refinery_operations · table¶
EIA API v2 petroleum refinery process data in tall format. One row per EIA area + series (process_code) + year-month. Key series include crude inputs to distillation (CRDISS), operable distillation capacity (CAPACITY), and utilization rate (UTIL). Additional series cover catalytic cracking, coking, reforming, and other secondary processes. Pivoting into wide format is done via the refinery_utilization_summary view. One row per area + series_id + report year-month.
| Column | Type | Null | Description |
|---|---|---|---|
report_ |
integer | no | Calendar year |
report_ |
integer | no | Calendar month (1-12) |
eia_ |
string | yes | EIA area code (e.g., PADD code or 'USA') |
padd |
string | yes | PADD district description or 'National' |
series_ |
string | yes | EIA API v2 series identifier. Encodes area plus refinery process; the process is also available decoded in process_code with its label in metric_name. Key process codes include CRDISS crude inputs to distillation and operable distillation capacity measures. This table is tall format: one row per (eia_area_code, series_id, year-month), so ALWAYS filter on series_id or process_code — units differ per process (see the units column) and national totals coexist with PADD districts. Enumerate with SELECT DISTINCT series_id, process_code, metric_name. |
process_ |
string | yes | EIA refinery process code |
metric_ |
string | yes | Metric description (e.g., 'Crude Oil Input to Atmospheric Crude Oil Distillation Units') |
units |
string | yes | Units of measure (e.g., 'Thousand Barrels per Day') |
value |
double | yes | Metric value |
eia_coal_mines · table¶
MSHA MinesProdYearly coal mine production data (pipe-delimited CSV ZIP). The transformer downloads MinesProdYearly.zip and Mines.zip, performs an inner join on mine_id, filters to coal mines (COAL_METAL_IND = 'C'), and returns one row per mine + subunit + year. Includes mine demographics, operator/controller identity, geographic location (lat/lon, county, state), mine type and status, production volume in short tons, employee count, annual hours, labor productivity, and average seam height (underground mines). The transformer filters by the requested year dimension. Cross-references geo.states via state_abbr. controller_name and operator_name are unstructured (no per-row id) — mine_id is per-mine, not per-company. ref.canonical_org_entity carries each as an already-resolved identity (eia_coal_controller_name, eia_coal_operator_name, each with an LEI when matched); join there on the name rather than re-running a fuzzy match against gleif_entities.legal_name by hand.
| Column | Type | Null | Description |
|---|---|---|---|
mine_ |
string | no | MSHA mine identifier |
report_ |
integer | no | Production report year |
mine_ |
string | yes | Mine name |
controller_ |
string | yes | Mine controller company name |
operator_ |
string | yes | Mine operator company name |
state_ |
string | yes | 2-letter state abbreviation (e.g., 'CA') |
county_ |
string | yes | 5-digit county FIPS code |
county_ |
string | yes | County name |
latitude |
double | yes | Mine latitude |
longitude |
double | yes | Mine longitude |
mine_ |
string | yes | Mine type (e.g., 'Surface', 'Underground') |
subunit_ |
string | no | MSHA subunit code (e.g., '01' = Underground, '02' = Surface, '03' = Auger) |
subunit |
string | yes | Subunit description |
mine_ |
string | yes | Mine status (e.g., 'Active', 'Temporarily Idled', 'Abandoned') |
production_ |
double | yes | Coal production in short tons |
avg_ |
double | yes | Average number of employees |
annual_ |
double | yes | Total employee hours worked |
labor_ |
double | yes | Labor productivity in short tons per employee hour |
avg_ |
double | yes | Average mine height in inches (underground mines only) |
ev_charging_stations · table¶
NREL Alternative Fuels Data Center (AFDC) public electric charging station registry — one row per station. Station-level port counts by charging level (ev_dc_fast_num / ev_level1_evse_num / ev_level2_evse_num) and available connector types (ev_connector_types, comma-separated — e.g. CHADEMO, J1772, J1772COMBO, TESLA). Does not model AFDC's per-charger connector/power breakdown (ev_charging_units) — deeper than any known query needs; the station-level aggregate counts and connector list answer "how much charging capacity exists where." Whole registry re-fetched and overwritten each run when Last-Modified changes (confirmed live: ~90K electric stations, 200-row page cap). Cross-references geo.states via state_abbr. Source: developer.nlr.gov (NREL's API host as of the 29 May 2026 migration off the retired developer.nrel.gov domain; confirmed live).
| Column | Type | Null | Description |
|---|---|---|---|
id |
long | no | AFDC station ID (PK) |
station_ |
string | yes | Station name |
street_ |
string | yes | Street address |
intersection_ |
string | yes | Free-text directions to the station |
city |
string | yes | City |
state_ |
string | yes | 2-letter state abbreviation (e.g., 'CA') |
zip |
string | yes | ZIP code |
country |
string | yes | ISO country code (station registry also covers CA/MX) |
latitude |
double | yes | Station latitude |
longitude |
double | yes | Station longitude |
access_ |
string | yes | 'public' or 'private' |
access_ |
string | yes | Free-text access hours |
access_ |
string | yes | Access restriction detail code, when access_code is private |
groups_ |
string | yes | Groups permitted access (e.g. 'Public', 'Private') |
facility_ |
string | yes | Facility type (e.g. 'FLEET_GOVT', 'HOTEL', 'PARKING_GARAGE') |
owner_ |
string | yes | Owner type code (e.g. 'LG'=local govt, 'SG'=state govt, 'P'=private, 'T'=utility) |
status_ |
string | yes | Station status ('E'=available, 'P'=planned, 'T'=temporarily unavailable) |
open_ |
date | yes | Date the station opened |
date_ |
date | yes | Date AFDC last confirmed this record |
expected_ |
date | yes | Expected opening date, for planned stations |
updated_ |
timestamp | yes | AFDC's last-updated timestamp for this record |
ev_ |
string | yes | Comma-separated connector types available (e.g. 'CHADEMO,J1772,J1772COMBO') |
ev_ |
integer | yes | Count of DC fast charging ports |
ev_ |
integer | yes | Count of Level 1 charging ports |
ev_ |
integer | yes | Count of Level 2 charging ports |
ev_ |
string | yes | Charging network operator (e.g. 'TESLA', 'CHARGEPOINT', 'Non-Networked') |
ev_ |
string | yes | Network operator website |
ev_ |
string | yes | Free-text pricing description |
ev_ |
boolean | yes | Whether this is workplace charging |
ev_ |
string | yes | On-site renewable generation source, when present |
restricted_ |
boolean | yes | Whether access is restricted |
maximum_ |
string | yes | Maximum vehicle class served (e.g. 'LD', 'MD', 'HD') |
station_ |
string | yes | Station contact phone number |
geocode_ |
string | yes | AFDC geocoding confidence status |
eia_drilling_activity · table¶
EIA Short-Term Energy Outlook (STEO) Table 10a upstream drilling activity — active rig count, new wells drilled, new wells completed, and drilled-but- uncompleted (DUC) well inventory, monthly, for the 6 regions STEO covers (Permian, Bakken, Eagle Ford, Appalachia, Haynesville, and Rest of Lower 48 excluding Gulf of America). This is the successor to EIA's standalone Drilling Productivity Report, folded into STEO as Table 10a in June 2024 (confirmed live: full 2013-01 through present history, 24 series, ~3,900 rows, one request). Rig counts/wells drilled lead crude and gas production by months, which energy's production/capacity tables alone cannot show. One row per (region, metric, period). Whole series set re-fetched and overwritten each run when content changes.
| Column | Type | Null | Description |
|---|---|---|---|
series_ |
string | no | EIA STEO series ID (e.g. 'RIGSPM'); PK component with period |
series_ |
string | yes | Full EIA series description |
region_ |
string | yes | DPR region code decoded from series_id (PM/BK/EF/AP/HA/R48) |
region_ |
string | yes | Region name decoded from series_id (Permian/Bakken/Eagle Ford/ Appalachia/Haynesville/Rest of Lower 48 excluding Gulf of America) |
metric_ |
string | yes | Metric decoded from series_id (RIGS/NWD/NWC/DUCS) |
metric_ |
string | yes | Metric name decoded from series_id (Active Rigs/New Wells Drilled/ New Wells Completed/Drilled but Uncompleted Wells) |
period |
string | no | Report period, YYYY-MM; PK component with series_id |
report_ |
integer | yes | Calendar year parsed from period |
report_ |
integer | yes | Calendar month (1-12) parsed from period |
value |
double | yes | Metric value — rig count and well counts are physical counts (not dollars/percent); DUC is an end-of-month inventory level, not a flow |
state_energy_mix · view¶
Annual renewable and fossil fuel generation mix by state. Reads eia_electricity_generation's own EIA-published rollup rows (energy_source_code ALL/FOS/REN/NUC at geo_level='state', sector_code='99' — "All Sectors") rather than re-summing individual fuel codes, since several of EIA's own leaf-looking codes are themselves nested rollups (e.g. COL is BIT+SUB+LIG) and summing them alongside their children double-counts. other_gen is a residual (total - fossil - renewable - nuclear) so the four categories always sum exactly to the total, rather than relying on EIA's own OTH code, which does not capture every non-fossil/non-renewable/non-nuclear source (e.g. pumped storage). other_gen can be slightly negative: EIA's own FOS/REN/NUC rollups do not always sum exactly to ALL, so treat it as a small balancing term rather than a clean physical category. Measured live across production, 69 of 255 complete state-years carry a negative residual, and its magnitude never exceeds 1.2% of that state-year's total in either direction — renewable_pct and fossil_pct are unaffected. eia_electricity_generation is MONTHLY and publishes no annual sentinel row, so every measure here is the sum of that state-year's monthly rollup rows. months_covered reports how many distinct months went into the sum: a year in progress, or one the source has only partly published, totals fewer than 12 months and is not comparable to a full year — filter on months_covered = 12 for year-over-year work. One row per state + year. State name comes from eia_electricity_generation's own state_description column (no join to geo.states, and no FIPS code is included).
View — columns are resolved by the query engine at runtime.
utility_scorecard · view¶
Utility-level performance scorecard joining EIA-861 annual survey data with aggregated operating capacity from EIA-860 power plants. One row per utility + report year. Shows entity type, state, customer counts, total sales, total revenue, and sum of net summer capacity across all operating generators owned by the utility.
View — columns are resolved by the query engine at runtime.
eia_electricity_demand_by_county · view¶
County-grain electricity demand apportioned from EIA-861 utility-level sales (eia_utility_annual) using the EIA-861 Service_Territory utility-to-county crosswalk (eia_service_territory). EIA-861 does not publish a per-county customer count or sales split within a utility's service territory, so each utility's customer counts, sales, and revenue are divided evenly across the N counties in its service-territory list for that year — a naive equal-split apportionment, not a per-county measurement. A utility with a single-county territory gets an exact (unsplit) figure for that county; a multi-county utility blurs real variation across its territory (a large city and a rural county served by the same utility get identical apportioned demand). Where more than one utility serves the same county, sum this view's rows for that county to get a total. county_fips is a best-effort join to the latest TIGER vintage of geo.counties (prefix match on EIA's un-suffixed county name against geo's 'X County'/'X Parish'/etc. name) and is null where no vintage match is found — treat it as an enrichment, not a guaranteed key. Requires the geo schema present in the same Calcite model.
View — columns are resolved by the query engine at runtime.
capacity_pipeline · view¶
Capacity additions and retirements from EIA-860M annual snapshots, aggregated by state, change year, technology, fuel category and change type. One row per state + change_year + change_month + technology + fuel_category + change_type. DEDUPLICATION: eia_capacity_changes is a cumulative snapshot in which a single event reappears in every later snapshot_year it survives into (see that table's comment), so this view first reduces to the newest snapshot per (plant_id, generator_id, change_year, change_type) before aggregating. Without that step the totals overstate by roughly 4x — measured live, the pre-deduplication figure for this view's own filter was 3,773,160 MW across 72,779 rows against 918,476 MW across 14,575 real events. NOT FORWARD-LOOKING, despite the view's name: no row in eia_capacity_changes carries a change_year beyond the current year, and the 'Planned Addition' and 'Cancellation' rows — the ones that would carry a pipeline date — have change_year NULL on every row, so they aggregate into a single NULL bucket rather than a future year. 'Retirement' rows are historical (1896-2023). Treat this as a record of capacity change, not a pipeline of announced projects, until the planned-date mapping is fixed. The source's change_type vocabulary is exactly: Addition (259,980 rows, 1891-2025), Retirement (58,060, 1896-2023), Planned Addition (14,719, year NULL) and Cancellation (12,725, year NULL). This view covers 'Planned Addition' and 'Retirement'; historical 'Addition' is deliberately excluded, which is why it is not a total-capacity view.
View — columns are resolved by the query engine at runtime.
weekly_gas_storage_signal · view¶
Weekly natural gas working gas storage levels (storage_type_code = 'SWO') with year-over-year comparison. Uses LAG window function to compute the prior year same-week volume for YoY delta and percent change calculation. One row per region + report date. Useful as a market signal for gas price forecasting.
View — columns are resolved by the query engine at runtime.
state_energy_burden · view¶
State-level energy burden estimate joining annual residential electricity prices with state energy consumption. Computes an implied annual residential electricity bill estimate from average price and total residential electricity sales divided by customer count. One row per state + year. State name comes from eia_electricity_prices' own state_description column (no join to geo.states).
View — columns are resolved by the query engine at runtime.
refinery_utilization_summary · view¶
Refinery utilization summary pivoted from tall eia_refinery_operations data. Uses CASE expressions on process_code/series_id to pivot key series into named columns: crude_input_kbd, operable_capacity_kbd, utilization_rate_pct (all taken directly from the source series), catalytic_cracking_kbd, coking_kbd, and reforming_kbd, plus a locally computed computed_utilization_pct (crude_input_kbd / operable_capacity_kbd). One row per EIA area + PADD + report year + report month.
View — columns are resolved by the query engine at runtime.