OilPriceAPI Docs
GitHub
GitHub
  • SDKs & Languages

    • SDKs & Language Guides
    • TypeScript Response Types
  • Language Guides

    • Java Oil Price API Integration | OilPriceAPI
    • Go Oil Price API Integration | OilPriceAPI
    • Rust Oil Price API Integration | OilPriceAPI
    • PHP Oil Price API Integration | OilPriceAPI
    • Ruby Oil Price API Integration | OilPriceAPI
    • C# .NET Oil Price API Integration | OilPriceAPI
    • R Language Oil Price API Integration | OilPriceAPI

Python Integration Guide

Integrate OilPriceAPI into your Python applications for real-time crude oil prices, Brent oil data, natural gas pricing, and energy commodity market information. Build solutions for commodities trading platforms, logistics applications, and fleet management systems.

There are two ways to call the API from Python:

  • The official oilpriceapi SDK (recommended) — typed, with retries and caching built in.
  • Raw HTTP with requests — zero SDK dependency, full control.

For the complete SDK reference (async client, alerts, pandas helpers) see the Python SDK Quick Start.

Requirements

  • Python 3.8 or higher
  • pip for installing packages

Installation

Install the official SDK:

pip install oilpriceapi

Or, if you prefer raw HTTP calls, install requests:

pip install requests

Quick Start

Using the official SDK

from oilpriceapi import OilPriceAPI

# Reads the OILPRICEAPI_KEY environment variable by default
client = OilPriceAPI()

# Get the latest WTI price
wti = client.prices.get("WTI_USD")
print(f"WTI: ${wti.value:.2f}")

Using requests (no SDK)

A single-commodity request returns a flat object at data:

import os
import requests

api_key = os.environ["OILPRICE_API_KEY"]

response = requests.get(
    "https://api.oilpriceapi.com/v1/prices/latest",
    params={"by_code": "WTI_USD"},
    headers={"Authorization": f"Token {api_key}"},
)
response.raise_for_status()

data = response.json()
print(f"WTI: {data['data']['formatted']}")   # e.g. "$68.58"
print(f"Price: {data['data']['price']}")      # e.g. 68.58

Complete API Client Class

import os
import requests


class OilPriceAPIError(Exception):
    """Base exception for API errors."""


class AuthenticationError(OilPriceAPIError):
    pass


class RateLimitError(OilPriceAPIError):
    pass


class OilPriceClient:
    BASE_URL = "https://api.oilpriceapi.com/v1"

    def __init__(self, api_key=None, timeout=30):
        self.api_key = api_key or os.environ.get("OILPRICE_API_KEY")
        if not self.api_key:
            raise ValueError("API key is required")
        self.timeout = timeout
        self.session = requests.Session()
        self.session.headers.update({
            "Authorization": f"Token {self.api_key}",
            "Accept": "application/json",
        })

    def _request(self, endpoint, params=None):
        response = self.session.get(
            f"{self.BASE_URL}{endpoint}",
            params=params,
            timeout=self.timeout,
        )

        if response.status_code == 401:
            raise AuthenticationError("Invalid or missing API key")
        if response.status_code == 429:
            raise RateLimitError("Rate limit exceeded")
        if response.status_code >= 400:
            raise OilPriceAPIError(f"API error: HTTP {response.status_code}")

        return response.json()

    def latest_price(self, code):
        """Get the latest price for a single commodity (flat `data` object)."""
        return self._request("/prices/latest", {"by_code": code})

    def latest_prices(self, codes):
        """Get several prices at once. A comma-separated request returns
        a `prices` array under `data`."""
        joined = ",".join(codes)
        return self._request("/prices/latest", {"by_code": joined})

    def historical_prices(self, code, period="past_week"):
        """period: past_day | past_week | past_month | historical"""
        return self._request(f"/prices/{period}", {"by_code": code})

    def commodities(self):
        return self._request("/commodities")

Usage Examples

Fetch a Single Price

client = OilPriceClient()

data = client.latest_price("WTI_USD")
price = data["data"]
print(f"{price['code']}: {price['formatted']} ({price['currency']})")

Fetch Multiple Commodities

A multi-code request returns an array under data['prices']:

client = OilPriceClient()

data = client.latest_prices(["WTI_USD", "BRENT_CRUDE_USD", "NATURAL_GAS_USD"])

for price in data["data"]["prices"]:
    print(f"{price['code']}: {price['formatted']}")

Look one up by code:

prices = {p["code"]: p for p in data["data"]["prices"]}
print(prices["WTI_USD"]["formatted"])

Historical Price Analysis

Historical endpoints return an array of points under data['prices']:

client = OilPriceClient()

history = client.historical_prices("WTI_USD", period="past_week")
points = history["data"]["prices"]

values = [p["price"] for p in points]
print(f"Points: {len(values)}")
print(f"Average: ${sum(values) / len(values):.2f}")
print(f"Range: ${min(values):.2f} - ${max(values):.2f}")

With pandas

import pandas as pd

client = OilPriceClient()
history = client.historical_prices("BRENT_CRUDE_USD", period="past_month")

df = pd.DataFrame(history["data"]["prices"])
df["created_at"] = pd.to_datetime(df["created_at"])
df = df.sort_values("created_at")

df["sma_5"] = df["price"].rolling(window=5).mean()
print(df[["created_at", "price", "sma_5"]].tail())

Django Integration

# services.py
from django.core.cache import cache

_client = OilPriceClient()


def current_price(code):
    cache_key = f"oil_price_{code}"
    cached = cache.get(cache_key)
    if cached is not None:
        return cached

    data = _client.latest_price(code)["data"]
    cache.set(cache_key, data, timeout=300)  # 5 minutes
    return data


# views.py
from django.http import JsonResponse


def wti_view(request):
    return JsonResponse(current_price("WTI_USD"))

Error Handling

The API returns different error shapes by status code:

  • 401 — a top-level error object with code: "UNAUTHORIZED".
  • 400 — status: "fail" with details under data.
import time
import requests


def fetch_with_retry(client, code, max_retries=3):
    for attempt in range(1, max_retries + 1):
        try:
            return client.latest_price(code)
        except RateLimitError:
            if attempt == max_retries:
                raise
            backoff = 2 ** attempt
            print(f"Rate limited, waiting {backoff}s "
                  f"(attempt {attempt}/{max_retries})")
            time.sleep(backoff)


# Inspecting the raw error body
response = requests.get(
    "https://api.oilpriceapi.com/v1/prices/latest",
    params={"by_code": "WTI_USD"},
    headers={"Authorization": "Token bad_key"},
)

if response.status_code == 401:
    body = response.json()
    print(body["error"]["code"])     # "UNAUTHORIZED"
    print(body["error"]["message"])

Common Commodity Codes

CodeDescription
WTI_USDWest Texas Intermediate Crude Oil
BRENT_CRUDE_USDBrent Crude Oil
NATURAL_GAS_USDNatural Gas (Henry Hub)
HEATING_OIL_USDHeating Oil No. 2
DIESEL_USDUltra Low Sulfur Diesel

View all 460+ commodity codes

Frequently Asked Questions

Is there an official SDK for Python?

Yes. Install it with pip install oilpriceapi and see the Python SDK Quick Start for the full reference, including the async client, price alerts, and pandas helpers. The raw requests examples above are provided for teams that prefer zero SDK dependencies.

How do I authenticate?

Send an Authorization: Token YOUR_API_KEY header on every request. The SDK reads the OILPRICEAPI_KEY environment variable automatically.

How do I handle rate limiting?

Implement exponential backoff when you receive a 429 response, as shown in the fetch_with_retry helper above. The official SDK retries automatically.

Related Resources

  • Python SDK Quick Start - Full official SDK reference
  • JavaScript Developer Guide - Node.js alternative
  • Ruby Developer Guide - Alternative language guide
  • Go Developer Guide - High-performance alternative
  • Authentication Guide - API key management
  • API Reference - Complete endpoint documentation
  • Rate Limiting - Usage limits and best practices
Last Updated: 7/3/26, 2:48 PM