OilPriceAPI insights

FRED oil price data in Python: the API and the CSV route

By OilPriceAPI · Published · Outputs run Nov 13, 2026 (UTC) with Python 3.14.7, requests 2.34.2 and pandas 3.1.1

FRED, the St. Louis Fed's data service, republishes the U.S. Energy Information Administration's daily WTI and Brent spot prices under the series IDs DCOILWTICO and DCOILBRENTEU. There are two ways to load them in Python: the documented FRED API, which needs a key, and a CSV download URL on fred.stlouisfed.org, which returned data without one.

1. The energy series IDs

Series IDFRED titleUnitsFrequency
DCOILWTICOCrude Oil Prices: West Texas Intermediate (WTI) - Cushing, OklahomaDollars per BarrelDaily
DCOILBRENTEUCrude Oil Prices: Brent - EuropeDollars per BarrelDaily
DHHNGSPHenry Hub Natural Gas Spot PriceDollars per Million BTUDaily
GASREGWUS Regular All Formulations Gas PriceDollars per GallonWeekly
GASDESWUS Diesel Sales PriceDollars per GallonWeekly

Source: each FRED series page, opened Nov 13, 2026. All five list the U.S. Energy Information Administration as their source.

2. The documented route: fred/series/observations

Every FRED API request needs a key. FRED's API key page says you request one from a fredaccount.stlouisfed.org user account, and that each application should have its own. The observations endpoint is described in the fred/series/observations documentation.

python -m pip install requests pandas
export FRED_API_KEY=YOUR_FRED_API_KEY
import os

import pandas as pd
import requests

URL = "https://api.stlouisfed.org/fred/series/observations"


def fred_observations(series_id: str, start: str) -> pd.Series:
    params = {
        "series_id": series_id,
        "api_key": os.environ["FRED_API_KEY"],
        "file_type": "json",
        "observation_start": start,
        "sort_order": "asc",
    }
    resp = requests.get(URL, params=params, timeout=30)
    if resp.status_code != 200:
        raise RuntimeError(f"FRED {resp.status_code}: {resp.text.strip()}")
    rows = resp.json()["observations"]
    values = pd.to_numeric(pd.Series({r["date"]: r["value"] for r in rows}), errors="coerce")
    values.index = pd.to_datetime(values.index)
    return values.rename(series_id)


print(fred_observations("DCOILWTICO", "2026-11-01"))

Per FRED's documentation, a JSON response has an observations list whose items carry a date and a value, and the value is a string (the documented example shows "1065.9"). The function converts values with pd.to_numeric for that reason.

We ran this function on Nov 13, 2026 with the demonstration key printed in FRED's docs, which is not a registered key. FRED answered HTTP 400 with the message "Bad Request. The value for variable api_key is not registered." With no api_key parameter at all it answered HTTP 400 with "Bad Request. Variable api_key is not set." If you see either, the key is the problem, not the series ID.

Parameters worth knowing

ParameterWhat FRED documents
api_keyRequired. A 32-character lowercase alphanumeric string.
series_idRequired. For example DCOILWTICO.
file_typexml, json, xlsx or csv. The default is xml, so set json explicitly.
observation_start, observation_endYYYY-MM-DD bounds on the observation dates.
limit1 to 100000 rows; the default is 100000. Page with offset.
sort_orderasc (default) or desc.
frequency, aggregation_methodAggregate to a lower frequency (for example m for monthly) by avg (default), sum or eop.
unitsA transformation such as pch (percent change) or pc1 (percent change from a year ago). The default, lin, returns levels.
realtime_start, realtime_end, vintage_datesRequest the data as it stood on earlier dates.

Source: fred/series/observations, read Nov 13, 2026.

Rate limit: FRED's errors page says up to 120 requests per minute are allowed before the API returns HTTP 429, and that not complying with the throttling can result in a temporary block.

3. The no-key route: the CSV download

FRED also serves a series as CSV at https://fred.stlouisfed.org/graph/fredgraph.csv?id=<SERIES>. It returned data without a key when we ran it, and pandas reads it directly. This URL is not part of FRED's API documentation, so it has no stated parameters, limits or stability promise: fine for a notebook, a poor base for a scheduled job. The cosd parameter in the sample set the start date in our run.

import pandas as pd

CSV = "https://fred.stlouisfed.org/graph/fredgraph.csv"


def fred_csv(series_id: str, start: str) -> pd.Series:
    frame = pd.read_csv(
        f"{CSV}?id={series_id}&cosd={start}",
        parse_dates=["observation_date"],
        index_col="observation_date",
        na_values=".",
    )
    return frame[series_id]


prices = pd.concat(
    [fred_csv("DCOILWTICO", "2026-11-01"), fred_csv("DCOILBRENTEU", "2026-11-01")],
    axis=1,
)
prices["brent_minus_wti"] = (prices["DCOILBRENTEU"] - prices["DCOILWTICO"]).round(2)
print(prices)
Output, run Nov 13, 2026 (UTC):
                  DCOILWTICO  DCOILBRENTEU  brent_minus_wti
observation_date                                           
2026-11-02            100.06        107.39             7.33
2026-11-03             99.64        107.03             7.39
2026-11-04             91.73         91.84             0.11
2026-11-05             94.05         97.96             3.91
2026-11-06             94.37         97.83             3.46
2026-11-09             90.40         91.03             0.63
2026-11-10             89.62         90.16             0.54
2026-11-11             89.62         92.14             2.52

Values are dollars per barrel. On Nov 13 the newest observation was dated Nov 11, 2026, the same date the EIA API returned that day for the underlying series (see the EIA API in Python tutorial). FRED is a second copy of a lagged EIA series, not a live quote.

4. Terms to read before you ship

FRED's API terms of use require an application to display this notice: "This product uses the FRED® API but is not endorsed or certified by the Federal Reserve Bank of St. Louis." They also state that data series available through the API may be owned by third parties and subject to copyright restrictions. Read the terms yourself; this paragraph is a pointer, not legal advice.

5. The same two series from OilPriceAPI

OilPriceAPI carries the same EIA spot series as WTI_SPOT_USD and BRENT_SPOT_USD. The request needs an OilPriceAPI key.

import os

import requests

resp = requests.get(
    "https://api.oilpriceapi.com/v1/prices/latest",
    params={"by_code": "WTI_SPOT_USD,BRENT_SPOT_USD"},
    headers={"Authorization": f"Token {os.environ['OILPRICEAPI_KEY']}"},
    timeout=30,
)
resp.raise_for_status()
for quote in resp.json()["data"]["prices"]:
    print(
        quote["code"],
        quote["price"],
        quote["source_date"],
        quote["source"],
        quote["data_status"],
    )
Output, run Nov 13, 2026 (UTC):
WTI_SPOT_USD 89.62 2026-11-11 eia_api current
BRENT_SPOT_USD 92.14 2026-11-11 eia_api current

The values and the Nov 11 source date match the last row of the FRED output above, and the response names eia_api as its source. All three services are serving one EIA series.

When FRED is the better choice

  • You are joining oil prices to economic series that FRED carries and we do not. OilPriceAPI is an energy and commodity price API.
  • You need data as it stood on an earlier date. FRED documents realtime_start, realtime_end and vintage_dates for that; we have no equivalent.
  • You want built-in transformations or frequency aggregation (the units and frequency parameters).

When our copy saves work

  • You already call OilPriceAPI for other codes and want the EIA spot series in the same request and JSON shape.
  • You want each value to arrive with its source date and a data_status field (current in the run above) rather than working out the lag yourself.

OilPriceAPI is not a replacement for FRED. We ran the request above with our own test key and did not check which plans include these two codes; see pricing for plan details.

Sources

  • FRED API keys: key format and account requirement. Read Nov 13, 2026.
  • FRED fred/series/observations: parameters, defaults and the response shape. Read Nov 13, 2026.
  • FRED API errors: status codes and the request limit. Read Nov 13, 2026.
  • FRED API terms of use: the required notice and third-party copyright statement. Read Nov 13, 2026.
  • fred.stlouisfed.org graph/fredgraph.csv, series DCOILWTICO and DCOILBRENTEU: retrieved Nov 13, 2026 (UTC).
  • api.oilpriceapi.com /v1/prices/latest, codes WTI_SPOT_USD and BRENT_SPOT_USD: retrieved Nov 13, 2026 (UTC).