OilPriceAPI Docs
GitHub
GitHub
  • Interactive Explorer

    • Interactive API Explorer
  • Price Data

    • API Reference
    • Get Latest Prices
    • Historical Prices
  • Commodities

    • List Commodities
    • Get Commodity Details
  • AI Agents (MCP)

    • Get Market Brief
    • Subscriptions / Watches
    • Agent Subscriptions with MCP
  • Marine Fuels

    • List Marine Fuel Ports
    • Get Port Details with Prices
  • Premium Endpoints

    • All Prices API - One Call, All Commodities
    • Cushing Oil Storage Intelligence API
    • Drilling Intelligence API
    • Marine Fuels API
    • ICE Brent Futures API
  • Futures

    • Futures API
    • ICE Brent Futures
    • ICE WTI Futures
    • ICE Gas Oil Futures
    • NYMEX Natural Gas Futures
    • ICE EUA Carbon Futures
  • Dark Data (Premium)

    • Energy Intelligence API
    • Rig Counts
    • Well Permits
    • Oil Inventories
    • OPEC Production
    • Drilling Productivity
    • Forecasts (STEO)
  • Well Production (Beta)

    • Well Production Data
    • Well Production API Reference
  • Analytics

    • Analytics API
  • Account & Billing

    • Account API

Historical Prices

Status: ✅ Available | 📈 Time-Series | 🔄 Multiple Intervals

Access historical price data for oil and commodity markets with customizable time ranges and intervals.

Endpoints

MethodEndpointDescription
GET/v1/prices/past_dayRaw spot price points for the past 24 hours
GET/v1/prices/past_weekRaw spot price points for the past 7 days
GET/v1/prices/past_monthRaw spot price points for the past 30 days
GET/v1/prices/past_yearRaw spot price points for the past 365 days

By default these endpoints return raw spot points captured roughly every 5–10 minutes — not pre-bucketed hourly/daily/weekly series. To get averaged buckets, pass the interval parameter (see below).

Authentication

See Authentication Guide for API key setup.

Parameters

ParameterTypeRequiredDescriptionDefaultExample
by_codestringNoCommodity code to retrieveBRENT_CRUDE_USDWTI_USD, NATURAL_GAS_USD
by_typestringNoPrice type to retrievespot_pricespot_price, daily_average_price
intervalstringNoTime interval for data aggregationrawraw, 1h, 1d, 1w, 1m
pageintegerNoPage number for pagination11, 2, 3
per_pageintegerNoNumber of results per page (max: 100)10010, 50, 100
formatstringNoResponse formatjsonjson, csv

Interval Parameter

The interval parameter controls time-based aggregation for historical data. When specified, prices are averaged within each time bucket, reducing data transfer and improving performance for charting and dashboard applications.

IntervalDescriptionAggregationUse Case
rawNo aggregation (default)Individual price pointsFull granularity, detailed analysis
1h, hourlyHourly aggregationAverage price per hourIntraday analysis, short-term trends
1d, dailyDaily aggregationAverage price per dayDaily charts, week-over-week comparison
1w, weeklyWeekly aggregationAverage price per weekMonthly/quarterly charts, medium-term trends
1m, monthlyMonthly aggregationAverage price per monthYearly charts, long-term trends

When an interval is supplied, each returned point has type set to the bucket average (e.g. daily_average), source set to aggregated, and an added price_type field.

Benefits:

  • Reduced Data Transfer: Fewer data points for the same time range (e.g., 30 days ≈ 30 daily averages vs. several thousand raw ~5–10 minute points)
  • Lower Rate Limit Usage: Aggregated responses use the same rate limit as raw data
  • Optimized for Charting: Pre-aggregated data is ideal for time-series visualizations
  • Consistent Formatting: All prices rounded to 2 decimal places for currency consistency

Response

Success (200) - Raw Data

data.prices is an array of raw spot points, roughly 5–10 minutes apart:

{
  "status": "success",
  "data": {
    "prices": [
      {
        "price": 67.84,
        "formatted": "$67.84",
        "currency": "USD",
        "code": "WTI_USD",
        "created_at": "2026-07-02T13:54:43.160Z",
        "updated_at": "2026-07-02T13:54:43.160Z",
        "type": "spot_price",
        "unit": "barrel",
        "source": "market_reporting"
      },
      {
        "price": 67.79,
        "formatted": "$67.79",
        "currency": "USD",
        "code": "WTI_USD",
        "created_at": "2026-07-02T13:46:11.402Z",
        "updated_at": "2026-07-02T13:46:11.402Z",
        "type": "spot_price",
        "unit": "barrel",
        "source": "market_reporting"
      }
    ]
  }
}

Success (200) - With Interval Aggregation

When using the interval parameter, points are bucket averages — type becomes the average type, source is aggregated, and a price_type field is added:

{
  "status": "success",
  "data": {
    "prices": [
      {
        "price": 67.94,
        "formatted": "$67.94",
        "currency": "USD",
        "code": "WTI_USD",
        "created_at": "2026-07-02T00:00:00.000Z",
        "type": "daily_average",
        "price_type": "daily_average",
        "source": "aggregated"
      },
      {
        "price": 68.41,
        "formatted": "$68.41",
        "currency": "USD",
        "code": "WTI_USD",
        "created_at": "2026-07-01T00:00:00.000Z",
        "type": "daily_average",
        "price_type": "daily_average",
        "source": "aggregated"
      }
    ]
  }
}

Response Fields

FieldTypeDescription
pricenumberPrice value (rounded to 2 decimal places)
formattedstringCurrency-formatted price with symbol
currencystringCurrency code (USD, EUR, GBP)
codestringCommodity code
created_atstringISO 8601 timestamp (UTC)
observed_atstringISO 8601 source observation timestamp when available; useful for daily official-source records
source_datestringDate-only source reference date when available, such as OPEC Basket daily values
updated_atstringISO 8601 timestamp of the last update (UTC) — raw points only
unitstringUnit of measure (e.g. barrel) — raw points only
typestringPrice type: spot_price for raw, or the bucket type (e.g. daily_average) for aggregated
price_typestringAdded only on aggregated points; mirrors the bucket average type
sourcestringData source: aggregated for interval data, or a source label (e.g. eia, market_reporting) for raw data

Pagination

Historical endpoints return paginated results for performance. The default and maximum page size is 100 items (per_page=100); page through larger ranges with page=N. Note the total-count header is X-Total (not X-Total-Count).

HeaderDescriptionExample
X-TotalTotal number of records2016
X-Total-PagesTotal number of pages21
X-PageCurrent page number1
X-Per-PageRecords per page100
LinkRFC 5988 pagination links<...?page=2>; rel="next"

OPEC Reference Basket

Use OPEC_BASKET_USD for the official OPEC Reference Basket price. The series is sourced from OPEC's official daily XML archive, uses source: "opec.org", and carries source_date for the OPEC reference date.

curl "https://api.oilpriceapi.com/v1/prices/historical?by_code=OPEC_BASKET_USD&start_date=2003-01-01&interval=daily" \
  -H "Authorization: Token YOUR_API_KEY"

OPEC Basket historical data is available on paid plans through the normal historical endpoints. Plan historical-depth limits still apply.

Examples

Basic Usage

# Get past 24 hours of raw WTI data (all individual price points)
curl "https://api.oilpriceapi.com/v1/prices/past_day?by_code=WTI_USD" \
  -H "Authorization: Token YOUR_API_KEY"

# Get past week with pagination
curl "https://api.oilpriceapi.com/v1/prices/past_week?by_code=WTI_USD&page=1&per_page=50" \
  -H "Authorization: Token YOUR_API_KEY"

# Get CSV format
curl "https://api.oilpriceapi.com/v1/prices/past_year?by_code=WTI_USD&format=csv" \
  -H "Authorization: Token YOUR_API_KEY"

Using Interval Aggregation

# Get past month as daily averages (~30 points instead of thousands of raw points)
curl "https://api.oilpriceapi.com/v1/prices/past_month?by_code=BRENT_CRUDE_USD&interval=1d" \
  -H "Authorization: Token YOUR_API_KEY"

# Get past year as weekly averages for long-term trending
curl "https://api.oilpriceapi.com/v1/prices/past_year?by_code=WTI_USD&interval=1w" \
  -H "Authorization: Token YOUR_API_KEY"

# Get past week as hourly averages for intraday analysis
curl "https://api.oilpriceapi.com/v1/prices/past_week?by_code=NATURAL_GAS_USD&interval=1h" \
  -H "Authorization: Token YOUR_API_KEY"

# Get past year as monthly averages for annual trends
curl "https://api.oilpriceapi.com/v1/prices/past_year?by_code=BRENT_CRUDE_USD&interval=1m" \
  -H "Authorization: Token YOUR_API_KEY"

JavaScript/TypeScript

// Get past week with daily aggregation
async function getWeeklyPrices() {
  const response = await fetch(
    "https://api.oilpriceapi.com/v1/prices/past_week?by_code=WTI_USD&interval=1d",
    {
      headers: {
        Authorization: "Token YOUR_API_KEY",
      },
    },
  );

  const data = await response.json();
  return data.data.prices; // Returns ~7 daily averages
}

// Get optimized data for charting (monthly averages for past year)
async function getChartData(commodityCode = "WTI_USD") {
  const response = await fetch(
    `https://api.oilpriceapi.com/v1/prices/past_year?by_code=${commodityCode}&interval=1m`,
    {
      headers: { Authorization: "Token YOUR_API_KEY" },
    },
  );

  const data = await response.json();

  // Format for chart libraries (e.g., Chart.js, Recharts)
  return data.data.prices.map((price) => ({
    date: new Date(price.created_at),
    value: price.price,
    formatted: price.formatted,
  }));
}

// Handle pagination for raw (non-aggregated) data
async function getAllRawData(
  endpoint = "past_week",
  commodityCode = "WTI_USD",
) {
  let allData = [];
  let page = 1;
  let totalPages = 1;

  while (page <= totalPages) {
    const response = await fetch(
      `https://api.oilpriceapi.com/v1/prices/${endpoint}?by_code=${commodityCode}&page=${page}`,
      {
        headers: { Authorization: "Token YOUR_API_KEY" },
      },
    );

    totalPages = parseInt(response.headers.get("X-Total-Pages"));
    const data = await response.json();

    if (data.data?.prices) {
      allData.push(...data.data.prices);
    }

    page++;
  }

  return allData;
}

Python

import requests
from datetime import datetime

# Get past month as daily averages
def get_monthly_averages(commodity_code='WTI_USD'):
    url = 'https://api.oilpriceapi.com/v1/prices/past_month'
    headers = {'Authorization': 'Token YOUR_API_KEY'}
    params = {
        'by_code': commodity_code,
        'interval': '1d'  # Daily aggregation
    }

    response = requests.get(url, headers=headers, params=params)
    data = response.json()

    return data['data']['prices']

# Get past year with weekly aggregation for trending
def get_yearly_trend(commodity_code='BRENT_CRUDE_USD'):
    url = 'https://api.oilpriceapi.com/v1/prices/past_year'
    headers = {'Authorization': 'Token YOUR_API_KEY'}
    params = {
        'by_code': commodity_code,
        'interval': '1w'  # Weekly aggregation
    }

    response = requests.get(url, headers=headers, params=params)
    data = response.json()

    # Format for data analysis
    prices = []
    for price in data['data']['prices']:
        prices.append({
            'date': datetime.fromisoformat(price['created_at'].replace('Z', '+00:00')),
            'price': price['price'],
            'type': price['type']
        })

    return prices

Errors

CodeStatusDescription
UNAUTHORIZED401Missing or invalid API key (returned as error.code)
invalid_code400Unknown commodity code (returned under data with status: "fail")

Rate Limits

All plans share the same request rate limit of 60 requests per rolling 60-second window per API key. Plans differ by monthly request quota, not by a per-endpoint rate ladder. Bursts within the window are fine. See Rate Limiting for details.

PlanRequests/MonthRequest Rate Limit
Free20060 per rolling 60s
Developer10,00060 per rolling 60s
Starter50,00060 per rolling 60s
Professional100,00060 per rolling 60s
Scale1,000,00060 per rolling 60s

Related Endpoints

  • Latest Prices - Current market prices
  • Commodities List - Available commodity codes
  • WebSocket Streaming - Real-time updates
Last Updated: 7/13/26, 10:16 AM
Prev
Get Latest Prices