Henry Hub Price API

Henry Hub Price API

You need a fast, reliable way to fetch the latest Henry Hub natural gas price for finance workflows—quoting, valuation, P&L explain, VaR shocks, or hedging dashboards. By the end of this guide, you will query the Energy API for the HENRY_HUB symbol, parse the response fields you actually need, and ship robust code that handles units, bases, caching, and non-trading days.

What you will build: a minimal, production-ready latest-price fetch for HENRY_HUB

This guide focuses on a single, finance-relevant task: reading the latest Henry Hub price and its date from the Energy API’s latest endpoint. You will:

Illustration: Henry Hub Price API
  • Call GET https://energy-api.com/api/v1/latest with your api_key and symbols=HENRY_HUB.
  • Extract rates.HENRY_HUB, dates.HENRY_HUB, and currencies.HENRY_HUB for valuation logic.
  • Respect unit semantics (USD/MMBtu) and base handling when mixing symbols.
  • Add minimal resilience: caching, date checking, and fallback behavior on non-trading days.

Origin catalog facts (verbatim)

  • Symbol name: Henry Hub
  • Symbol code: HENRY_HUB
  • Unit: USD/MMBtu
  • Auth: api_key query parameter. Placeholder YOUR_API_KEY only.
  • Do not pass base=USD when you also need TTF_GAS or EUA_CO2.
  • No MCP host. Starter $19.99/mo, trial 7 days / 50 calls.
  • curl: curl -G "https://energy-api.com/api/v1/latest" --data-urlencode "symbols=HENRY_HUB" --data-urlencode "api_key=YOUR_API_KEY"
  • Read rates.HENRY_HUB, dates.HENRY_HUB, currencies.HENRY_HUB. base may be MIXED.

Endpoint and authentication

The latest price endpoint is a simple GET with query parameters. Authentication uses an api_key in the query string—no headers required. Replace YOUR_API_KEY with your actual key when you deploy.

Endpoint:

  • GET https://energy-api.com/api/v1/latest
  • Required params for this guide: symbols=HENRY_HUB, api_key=YOUR_API_KEY

Do not add a base parameter for this single-symbol read. If you later request multiple symbols including TTF_GAS or EUA_CO2, do not force base=USD because the base may be MIXED, and you should rely on currencies.{symbol} to interpret units correctly.

Copy-paste cURL for HENRY_HUB

Use this exact request. It is safe to run as-is after substituting your real key:

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

Official samples you must understand

Official cURL (live)

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

Official JSON (live)

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

This official sample shows field shapes and the base behavior. Even though it’s for a different symbol, the structure (success, date, base, rates, dates, currencies, base_filter_note) is the same you will read for HENRY_HUB.

Real API response for HENRY_HUB (use these exact values in your tests)

The following is a real response sample for the symbol in scope. Use it to validate your parser and unit checks.

{"success":true,"date":"2026-10-14","base":"USD","rates":{"HENRY_HUB":3.22},"dates":{"HENRY_HUB":"2026-10-14"},"currencies":{"HENRY_HUB":"USD"},"base_filter_note":null}

Interpretation for finance:

  • rates.HENRY_HUB = 3.22 is the latest price.
  • currencies.HENRY_HUB = USD and the unit is USD/MMBtu (per origin catalog facts).
  • dates.HENRY_HUB = 2026-10-14 is the effective price date (ISO-8601).
  • base = USD applies to the symbol set in this call. If you query multiple symbols across currencies, base could be MIXED—always trust currencies.{symbol} for valuation.

More complete JSON blocks (for parser validation and regression tests)

You can reuse the same real response to test idempotency, caching, and parsing across environments. Keep them byte-identical to validate pure string comparisons in your tests.

Idempotent fetch example (same real response)

{"success":true,"date":"2026-10-14","base":"USD","rates":{"HENRY_HUB":3.22},"dates":{"HENRY_HUB":"2026-10-14"},"currencies":{"HENRY_HUB":"USD"},"base_filter_note":null}

Monitoring log example (same real response)

{"success":true,"date":"2026-10-14","base":"USD","rates":{"HENRY_HUB":3.22},"dates":{"HENRY_HUB":"2026-10-14"},"currencies":{"HENRY_HUB":"USD"},"base_filter_note":null}

Python example: fetch, validate, convert to a finance-friendly record

This example calls the same endpoint, reads the required fields, and outputs a normalized record you can pass to pricers, P&L explainers, or a market data cache.

import os
import time
import json
import urllib.parse
import urllib.request
from datetime import datetime, timezone

API_URL = "https://energy-api.com/api/v1/latest"
API_KEY = os.getenv("ENERGY_API_KEY", "YOUR_API_KEY")
SYMBOL = "HENRY_HUB"

def fetch_latest(symbol: str):
params = {
"symbols": symbol,
"api_key": API_KEY
}
url = API_URL + "?" + urllib.parse.urlencode(params)
req = urllib.request.Request(url, method="GET")
with urllib.request.urlopen(req, timeout=10) as resp:
payload = resp.read().decode("utf-8")
return json.loads(payload)

def to_finance_record(payload: dict, symbol: str):
# Required fields based on origin catalog facts
price = payload["rates"][symbol]
price_ccy = payload["currencies"][symbol] # Expect "USD" for HENRY_HUB
price_date = payload["dates"][symbol] # ISO string like "2026-10-14"
base = payload.get("base") # Could be "USD" or "MIXED" in multi-symbol scenarios

# Construct a finance-ready dict with explicit unit semantics
record = {
"symbol": symbol,
"price": float(price),
"unit": "USD/MMBtu", # From catalog
"price_currency": price_ccy,
"price_date": price_date, # valuation date for mid/close
"base": base,
"fetched_at_utc": datetime.now(timezone.utc).isoformat(timespec="seconds")
}
return record

def main():
data = fetch_latest(SYMBOL)
if not data.get("success"):
raise RuntimeError("Energy API call unsuccessful")

# Basic integrity checks
for key in ("rates", "dates", "currencies"):
if key not in data or SYMBOL not in data[key]:
raise KeyError(f"Missing {key}.{SYMBOL} in response")

rec = to_finance_record(data, SYMBOL)
print(json.dumps(rec, indent=2))

if __name__ == "__main__":
main()

Notes:

  • Unit is always USD/MMBtu for HENRY_HUB.
  • Use currencies.HENRY_HUB (USD) to validate the downstream ledger currency.
  • Keep fetched_at_utc as a monotonic timestamp for audit and replay.
  • Do not force a base parameter on this call.

Field-level mapping to finance workflows

  • rates.HENRY_HUB → price point for valuation and risk. Treat as a latest fix for the date in dates.HENRY_HUB.
  • dates.HENRY_HUB → valuation date. If your system requires end-of-day consistency, rate-limit updates and pin to this date for a given run.
  • currencies.HENRY_HUB → should be USD; this, combined with unit USD/MMBtu, drives P&L in USD unless you re-express in another currency in your stack.
  • base → relevant if you query multiple symbols. For Henry Hub solo reads, base will typically match the symbol currency; always validate before conversion.

Caching, non-trading days, and refresh strategy

Energy spot and benchmark series may not update on certain days. For finance jobs (EOD valuation, risk re-runs):

  • Cache responses keyed by dates.HENRY_HUB and invalidate only when the date changes or after a predetermined TTL (for example, a few hours) aligned with your batch window.
  • If you receive the same date across multiple fetches, do not force a refresh. Use the cached price to keep portfolio reconciliation stable.
  • Handle nulls defensively: if success is false or required fields are missing, alert and fall back to the last-known-good record for that symbol/date.
  • When fetching multiple symbols, expect base to be MIXED in some portfolios (e.g., if you include TTF_GAS or EUA_CO2). Do not set base=USD in that scenario; compute conversions in your stack if necessary.

Minimal validator: assert the shape before storing

Enforce that the response includes success, base, and maps for rates, dates, and currencies keyed by HENRY_HUB. Reject or quarantine records missing any of those keys to prevent silent downstream failures.

Common misuse and how to avoid it

  • Forcing base=USD when also requesting TTF_GAS or EUA_CO2. Avoid this—mixes can be valid and the API may label base as MIXED. Always read currencies.{symbol}.
  • Ignoring dates.HENRY_HUB. Do not assume today’s date equals the price date; persist the provided date for auditability and correct cutover.
  • Assuming units are interchangeable. HENRY_HUB is USD/MMBtu; do not combine it numerically with power prices (EUR/MWh) or emissions (EUR/tCO2) without unit conversion.

How to QA your pipeline with real samples

Use the provided samples to validate your parsing, and pin snapshot tests to exact JSON. Here are three complete blocks you can drop into tests today:

Real HENRY_HUB sample (validation)

{"success":true,"date":"2026-10-14","base":"USD","rates":{"HENRY_HUB":3.22},"dates":{"HENRY_HUB":"2026-10-14"},"currencies":{"HENRY_HUB":"USD"},"base_filter_note":null}

Official sample (shape and base behavior)

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

Real HENRY_HUB sample (regression pin)

{"success":true,"date":"2026-10-14","base":"USD","rates":{"HENRY_HUB":3.22},"dates":{"HENRY_HUB":"2026-10-14"},"currencies":{"HENRY_HUB":"USD"},"base_filter_note":null}

Implementation checklist for finance teams

  • Authentication: store api_key in a secure secret manager; inject at runtime.
  • Endpoint: GET /api/v1/latest with symbols=HENRY_HUB and api_key param only.
  • Parsing: read rates.HENRY_HUB, dates.HENRY_HUB, currencies.HENRY_HUB, and base.
  • Unit control: persist “USD/MMBtu” alongside the value for audit and conversions.
  • Caching: key by (symbol, dates.HENRY_HUB), with TTL aligned to your batch cadence.
  • Monitoring: alert on missing fields, success=false, or unexpected currency.
  • Trial and plan: Starter is $19.99/mo; trial is 7 days / 50 calls—budget your calls to validate your pipeline without throttling.

Error handling and fallback logic

Sample decision tree:

  • HTTP failure → retry with exponential backoff up to a small cap (e.g., 2–3 attempts) to stay within trial quotas.
  • success=false → log and fall back to last-known-good for the symbol and date.
  • Missing rates.HENRY_HUB/dates.HENRY_HUB/currencies.HENRY_HUB → quarantine the payload, do not update cache; escalate.
  • Date drift (dates.HENRY_HUB unchanged across refreshes) → keep cached price; only replace when the date changes.

Practical notes that save time

  • Timezone: dates.HENRY_HUB is an ISO-8601 date (no time). Align your valuation cutover to the date provided, not local server time.
  • Idempotency: same date should not invalidate caches; make your ingestion idempotent by symbol+date.
  • Serialization: store numeric prices as decimals if your ledger requires exact arithmetic; the API returns numeric JSON values you can parse to Decimal in Python.
  • Multiple symbols: if you expand beyond HENRY_HUB, avoid forcing base=USD when including TTF_GAS or EUA_CO2; handle per-symbol currency.

FAQ

Q: Which fields do I need for a basic valuation?
A: rates.HENRY_HUB (numeric price), dates.HENRY_HUB (price date), and currencies.HENRY_HUB (currency). Persist the known unit USD/MMBtu with the record.

Q: Should I pass a base parameter?
A: Not for a single-symbol HENRY_HUB read. If you add symbols like TTF_GAS or EUA_CO2, do not pass base=USD; rely on currencies.{symbol} and convert in your stack if needed.

Q: How do I handle days without updates?
A: Use dates.HENRY_HUB to detect staleness. If the date hasn’t advanced, keep using the cached value for that date. Raise alerts only when an expected cutover is missed beyond your tolerance.

Q: What are the plan details for trying this out?
A: Starter is $19.99/mo. The trial is 7 days with 50 calls—sufficient for a dev spike and CI test runs if you cache locally.

Q: Where do I find the full parameter list and symbol coverage?
A: See the official API reference in the documentation link below.

Next step: register and ship

Spin up your pipeline today. Create an account, grab your API key, and use the samples above to get a green CI run. Then wire the normalized record into your valuation/risk jobs.

Register • Documentation

Ready to get started?

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

Get API Key

Related posts