OilPriceAPI Docs
GitHub
GitHub
  • Interactive Explorer

    • Interactive API Explorer
  • Price Data

    • API Reference
    • Get Latest Prices
    • Historical Prices
    • Batch Prices
    • Excel Latest Price Gateway
    • Price Widget Endpoints
    • Price Utility Endpoints
    • Natural Gas Intelligence
  • Commodities

    • List Commodities
    • Get Commodity Details
    • Data Publication & Collection Schedules
  • AI Agents (MCP)

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

    • Marine Fuel API
    • List Marine Fuel Ports
    • Get Port Details with Prices
    • Bunker Fuels
    • Maritime Fuels
  • Fuel Surcharges

    • Fuel Surcharge API
  • Premium Endpoints

    • All Prices API - One Call, All Commodities
    • Cushing Oil Storage Intelligence API
    • Drilling Intelligence API
    • Marine Fuels API
    • ICE Brent Futures API
    • Benchmark Close
    • Aviation Fuel Pilot
  • Spreads & Margins

    • Spreads & Margins
    • Crack Spreads
    • Basis Spreads
    • Refining Margins
    • Curve Structure
    • Physical Premiums
  • Market Indicators

    • Market Indicators
    • Fuel Switching
    • Price Context
    • Storage Analytics
    • CFTC Positioning
    • Congressional Trades
    • Market Annotations
  • Futures

    • Futures API
    • ICE Brent Futures
    • ICE WTI Futures
    • ICE Gas Oil Futures
    • NYMEX Natural Gas Futures
    • ICE EUA Carbon Futures
    • EU Carbon Futures
    • TTF Gas Futures
    • LNG JKM Futures
    • UK Carbon Futures
  • Dark Data (Premium)

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

    • Well Production Data
    • Well Production API Reference
  • Analytics

    • Analytics API
  • Webhooks API

    • Webhooks API Reference
    • Webhook Endpoint Reference
  • Alerts

    • Price Alerts API
  • Account & Billing

    • Account API
    • API Keys
    • Subscriptions
    • Organizations

Get Latest Prices

Status: ✅ Available | 🕒 Source timestamps | 📊 Catalog endpoint

Returns the latest available price for a commodity, with source and freshness context when available. Call with a single by_code, or pass a comma-separated list to get several at once. Called with no by_code, it returns a single default commodity (BRENT_CRUDE_USD) — not every commodity.

GET/v1/prices/latest

Authentication

See Authentication Guide for API key setup.

Parameters

ParameterTypeRequiredDescription
by_codestringNoCommodity code, or several comma-separated (e.g. WTI_USD,BRENT_CRUDE_USD). Omit to get the default code.

Response

Success (200) — Single commodity

data is a flat price object (not nested by commodity code):

{
  "status": "success",
  "data": {
    "price": 68.58,
    "formatted": "$68.58",
    "currency": "USD",
    "code": "WTI_USD",
    "created_at": "2026-07-03T13:43:01.099Z",
    "updated_at": "2026-07-03T13:43:01.099Z",
    "type": "spot_price",
    "unit": "barrel",
    "source": "market_reporting",
    "data_status": "current",
    "freshness": {
      "status": "current",
      "age_seconds": 275,
      "expected_max_age_seconds": 1800
    },
    "changes": {
      "24h": {
        "amount": 0.72,
        "percent": 1.06,
        "previous_price": 67.86,
        "previous_timestamp": "2026-07-02T13:43:01Z",
        "measured_at": "2026-07-03T13:43:01Z",
        "span_hours": 24.0
      },
      "7d": { "amount": -1.01, "percent": -1.45, "previous_price": 69.59 },
      "30d": { "amount": -26.41, "percent": -27.8, "previous_price": 94.99 },
      "90d": { "amount": -42.96, "percent": -38.52, "previous_price": 111.54 }
    },
    "metadata": {
      "source": "market_reporting",
      "source_description": "Investing.com"
    }
  }
}

Success (200) — Multiple commodities

When you pass several codes, prices come back as an array under data.prices (not keyed by code), alongside a data.metadata block:

{
  "status": "success",
  "data": {
    "prices": [
      {
        "price": 68.58,
        "code": "WTI_USD",
        "formatted": "$68.58",
        "currency": "USD",
        "type": "spot_price",
        "unit": "barrel",
        "data_status": "current"
      },
      {
        "price": 71.98,
        "code": "BRENT_CRUDE_USD",
        "formatted": "$71.98",
        "currency": "USD",
        "type": "spot_price",
        "unit": "barrel",
        "data_status": "current"
      }
    ],
    "metadata": {
      "request_id": "6390b34903a8d3f0",
      "timestamp": "2026-07-03T13:47:37Z",
      "version": "v1"
    }
  }
}

Response Fields

Note: For a single code the price object sits directly in data. For multiple codes the objects are in the data.prices array.

FieldTypeDescription
pricenumberCurrent price value (rounded to 2 decimals)
formattedstringPrice formatted with currency symbol (e.g., "$68.58")
currencystringPrice currency code (USD, EUR, GBP)
codestringCommodity code (e.g., "WTI_USD")
created_atstringISO 8601 timestamp with milliseconds (UTC)
observed_atstringISO 8601 source observation timestamp when available; for source-dated daily data this is the reference date
source_datestringDate-only source reference date when available, e.g. OPEC Basket daily values
updated_atstringISO 8601 timestamp of the last update (UTC)
typestringPrice type, e.g. "spot_price"
unitstringUnit of measure (e.g. "barrel")
sourcestringData source identifier
data_statusstringFreshness label, e.g. "current"
freshnessobjectstatus, age_seconds, expected_max_age_seconds — how recent the point is
changesobjectPrice moves keyed by window (24h, 7d, 30d, 90d) — see Price changes below
metadata.sourcestringData source identifier
metadata.source_descriptionstringHuman-readable description of the data source

Price changes

Every /v1/prices/latest response carries a changes object. There is no parameter to request it — it is always included, and it costs no additional API call.

Each window is an object:

FieldTypeDescription
amountnumberAbsolute move in the price currency (e.g. 0.72 = up $0.72)
percentnumberPercentage move (e.g. 1.06 = up 1.06%)
previous_pricenumberThe price compared against
previous_timestampstringISO 8601 timestamp of that earlier price
measured_atstringISO 8601 timestamp of the current price
span_hoursnumberHours actually spanned between the two points — may exceed the window label
const pct = response.data.changes["24h"].percent; // 1.06

span_hours — read this before rendering a daily ticker

A 24h change legitimately spans longer than 24 hours when the market was closed. A Monday quote compares against Friday, so span_hours will read around 72.0. This is correct, not an error — we publish the span we actually measured rather than asserting the label, so you can decide whether to render it.

If you display a "today's move" figure, check span_hours before labelling it as such.

A window may be absent — check before reading it

When no honest comparison exists, the window is omitted rather than reported as zero. This happens when no price was published within the permitted lookback (for 24h, a generous multi-day allowance that absorbs weekends and holidays, but not a weekly-published series), and on the rare occasion a stale-price fallback is served — in that case the entire changes object is absent.

Omission is deliberate: a fabricated percentage is worse than no percentage. Sparsely-published commodities may never carry a 24h window at all.

Always guard before reading:

const c = response.data.changes?.["24h"];
if (c) console.log(`${c.percent}% over ${c.span_hours}h`);

Embedded devices should do the same — on Arduino, use an ArduinoJson filter to keep only the fields you need rather than growing the document buffer.

Windows available by plan

PlanWindows returned
Free, Developer, Exploration24h
Starter24h, 7d
Professional, Production24h, 7d, 30d
Scale, Reservoir, Enterprise24h, 7d, 30d, 90d

Windows above your plan are omitted from the object — the response shape is otherwise unchanged.

Errors

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

Examples

# Get the default commodity (BRENT_CRUDE_USD)
curl "https://api.oilpriceapi.com/v1/prices/latest" \
  -H "Authorization: Token YOUR_API_KEY"

# Get a specific commodity
curl "https://api.oilpriceapi.com/v1/prices/latest?by_code=WTI_USD" \
  -H "Authorization: Token YOUR_API_KEY"

# Get multiple commodities (returned as a data.prices array)
curl "https://api.oilpriceapi.com/v1/prices/latest?by_code=WTI_USD,BRENT_CRUDE_USD" \
  -H "Authorization: Token YOUR_API_KEY"

# Get the latest official OPEC Reference Basket price
curl "https://api.oilpriceapi.com/v1/prices/latest?by_code=OPEC_BASKET_USD" \
  -H "Authorization: Token YOUR_API_KEY"

OPEC Basket responses include source-date fields:

{
  "status": "success",
  "data": {
    "price": 69.33,
    "formatted": "$69.33",
    "currency": "USD",
    "code": "OPEC_BASKET_USD",
    "created_at": "2026-07-02T12:00:00.000Z",
    "observed_at": "2026-07-02T12:00:00.000Z",
    "source_date": "2026-07-02",
    "type": "spot_price",
    "unit": "barrel",
    "source": "opec.org"
  }
}
// JavaScript
async function getLatestPrice() {
  const response = await fetch(
    "https://api.oilpriceapi.com/v1/prices/latest?by_code=WTI_USD",
    {
      headers: {
        Authorization: "Token YOUR_API_KEY",
      },
    },
  );

  const data = await response.json();

  // For a single code, the price object is directly in data.data
  console.log(`Current price: ${data.data.formatted}`); // "$68.58"
  console.log(`Numeric value: ${data.data.price}`); // 68.58
  console.log(`24h change: ${data.data.changes["24h"].percent}%`);
  console.log(`Source: ${data.data.metadata.source_description}`);

  return data.data.price;
}
# Python
import requests

def get_latest_price(commodity_code='WTI_USD'):
    url = 'https://api.oilpriceapi.com/v1/prices/latest'
    headers = {'Authorization': 'Token YOUR_API_KEY'}
    params = {'by_code': commodity_code}

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

    price = data['data']['price']
    formatted = data['data']['formatted']

    print(f"Current {commodity_code}: {formatted}")
    return price

# Get multiple commodities. With several codes, prices are in data['prices']
def get_multiple_prices(codes=['WTI_USD', 'BRENT_CRUDE_USD', 'NATURAL_GAS_USD']):
    url = 'https://api.oilpriceapi.com/v1/prices/latest'
    headers = {'Authorization': 'Token YOUR_API_KEY'}
    params = {'by_code': ','.join(codes)}

    response = requests.get(url, headers=headers, params=params)
    prices = response.json()['data']['prices']  # a list, not keyed by code
    return {p['code']: p for p in prices}
# Ruby
require 'net/http'
require 'json'
require 'uri'

def get_latest_price(commodity_code = 'WTI_USD')
  uri = URI("https://api.oilpriceapi.com/v1/prices/latest?by_code=#{commodity_code}")

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Get.new(uri)
  request['Authorization'] = 'Token YOUR_API_KEY'

  response = http.request(request)
  data = JSON.parse(response.body)

  price = data['data']['price']
  puts "Current #{commodity_code}: $#{price}"

  price
end

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 request rate. 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

Rate limit headers are included in responses. X-RateLimit-Limit / -Remaining / -Used track your monthly quota:

X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9876
X-RateLimit-Reset: 1785542399

Best Practices

  • Cache responses: Use the response freshness block and source timestamps to decide when to refetch; cadence varies by source, market hours, dataset, and plan
  • Request specific commodities: Use by_code when possible, comma-separated for several at once
  • Handle rate limits: Check X-RateLimit-* headers and implement backoff

Related Endpoints

  • Historical Prices - Past price data
  • Commodities List - Available commodity codes
  • WebSocket Transport - Availability depends on account entitlement
Last Updated: 8/7/26, 4:09 PM
Prev
API Reference
Next
Historical Prices