OilPriceAPI Docs
Quick Start
API Reference
  • SDKs and languages
  • Tutorials
  • Articles
  • Documentation directory
  • Quick reference
  • API explorer
  • FAQ
  • Changelog
  • Status
  • Dashboard
GitHub
Quick Start
API Reference
  • SDKs and languages
  • Tutorials
  • Articles
  • Documentation directory
  • Quick reference
  • API explorer
  • FAQ
  • Changelog
  • Status
  • Dashboard
GitHub
  • Use Case Tutorials

    • Use Case Tutorials
    • Dashboard Building
    • Price Alerts
    • Data Analysis
    • Integration Patterns

Dashboard Building

Build a real-time energy price dashboard backed by OilPriceAPI: fetch all prices efficiently, cache them, choose sensible update intervals, and render charts.

Problem

You want to display live oil, gas, and energy commodity prices on an internal or customer-facing dashboard. A naive implementation calls the API once per widget on every page load, which:

  • Burns through your rate limit and request quota.
  • Adds latency to every render.
  • Hammers the API with redundant requests for data that only changes every few minutes.

The goal is a dashboard that feels instant, stays fresh, and uses a minimal number of API calls.

Solution Architecture

Put a small caching layer between your dashboard and OilPriceAPI:

Browser ──> Your backend (cache) ──> OilPriceAPI /prices/latest
   ^               |
   └─ polls ───────┘  (served from cache, refreshed on an interval)
  • Single batch fetch. Pull every commodity you need with one call to the "all prices" endpoint instead of one call per ticker.
  • Server-side cache. Store the latest response in memory (or Redis) with a short TTL.
  • Scheduled refresh. A background job refreshes the cache on a fixed interval; the browser reads from your cache, never directly from OilPriceAPI.

Code Implementation

Fetching all prices efficiently

/v1/prices/latest returns one price object by default. To batch, pass a comma-separated by_code list — up to 20 codes in a single call, billed as one request:

curl -H "Authorization: Token YOUR_API_KEY" \
  "https://api.oilpriceapi.com/v1/prices/latest?by_code=BRENT_CRUDE_USD,WTI_USD,NATURAL_GAS_USD,DIESEL_USD"

A multi-code call returns data.prices[], one object per code. If you want every commodity we publish rather than a chosen list, use /v1/prices/all instead.

Caching strategies

A read-through cache with a short TTL keeps the dashboard snappy while bounding your API usage. Crude benchmarks update every few minutes during market hours, while refined products (gasoline, diesel) update roughly twice a day — so a 60-second TTL is only worth it for the crude tiles.

Plan fit: a 60-second refresh is 1,440 requests/day (~43,000/month). That exceeds the Free plan (50 requests/day) and the Developer plan (10,000/month); it fits Starter (50,000/month) and above. Two ways to run it cheaper: poll less often (a 5-minute refresh is ~8,600/month, inside Developer), and send If-None-Match on every poll — an unchanged price returns 304 Not Modified, which does not count against your quota.

import time
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.oilpriceapi.com/v1"
CACHE_TTL_SECONDS = 60

CODES = "BRENT_CRUDE_USD,WTI_USD,NATURAL_GAS_USD,DIESEL_USD"  # up to 20 codes

_cache = {"prices": None, "etag": None, "fetched_at": 0}


def get_latest_prices():
    """Return cached prices, refreshing only when the TTL has expired."""
    now = time.time()
    if _cache["prices"] is None or now - _cache["fetched_at"] > CACHE_TTL_SECONDS:
        headers = {"Authorization": f"Token {API_KEY}"}
        if _cache["etag"]:
            headers["If-None-Match"] = _cache["etag"]  # 304s don't count against quota
        resp = requests.get(
            f"{BASE_URL}/prices/latest",
            headers=headers,
            params={"by_code": CODES},
            timeout=10,
        )
        if resp.status_code == 304:
            _cache["fetched_at"] = now  # unchanged — keep serving the cached copy
            return _cache["prices"]
        resp.raise_for_status()
        _cache["prices"] = resp.json()["data"]["prices"]  # one object per code
        _cache["etag"] = resp.headers.get("ETag")
        _cache["fetched_at"] = now
    return _cache["prices"]

Update intervals

Match your refresh interval to how often the underlying data changes. Polling faster than the data updates wastes quota without improving freshness.

Data typeTypical change frequencySuggested refresh
Crude spot prices (Brent, WTI)Every few minutes60 seconds
Refined products (gasoline, diesel)Roughly twice a day15–30 minutes
Daily settlementsOnce per day15–30 minutes
Historical/EODOnce per dayOn demand

Chart integration

Feed the cached payload into any charting library. Below is a minimal Chart.js example that renders a sparkline of recent values.

async function renderChart() {
  const res = await fetch("/api/dashboard/prices"); // your cached endpoint
  // A multi-code /prices/latest call returns { data: { prices: [...] } } —
  // one object per commodity code, not a time series.
  const { data } = await res.json();
  const byCode = Object.fromEntries(data.prices.map((p) => [p.code, p]));
  const brent = byCode["BRENT_CRUDE_USD"];

  new Chart(document.getElementById("brent"), {
    type: "bar",
    data: {
      labels: data.prices.map((p) => p.code),
      datasets: [
        {
          label: `Latest prices (Brent: $${brent.price}/bbl)`,
          data: data.prices.map((p) => p.price),
        },
      ],
    },
    options: { responsive: true, scales: { y: { beginAtZero: false } } },
  });
}

Best Practices

  • Serve the dashboard from your cached endpoint, never directly from the browser to OilPriceAPI (this also keeps your API key off the client).
  • Use one batch request for all tickers instead of N per-ticker requests.
  • Send If-None-Match/ETag on every poll. An unchanged price returns 304 Not Modified, which transfers no data and does not count against your request quota — see Conditional requests.
  • Show a "last updated" timestamp so users know how fresh the data is.
  • Degrade gracefully: if a refresh fails, keep serving the last good cache entry rather than showing an error.

Common Pitfalls

  • Polling faster than the data changes. A 1-second refresh against a source that publishes daily used to burn quota for nothing. Use conditional requests so unchanged polls cost you nothing, and check the response freshness metadata to see how current the value actually is.
  • Caching per request instead of per process. A cache that lives inside a single request handler never gets a hit. Use a shared store (module-level, Redis, or memcached).
  • Exposing your API key in frontend code. Always proxy through your backend.
  • No error fallback. A transient API hiccup should not blank out the whole dashboard — serve stale-but-valid data and retry in the background.
Last Updated: 9/5/26, 8:08 PM
Prev
Use Case Tutorials
Next
Price Alerts