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
  • 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
    • Demo API (No Authentication)
    • 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
    • European Gasoil Crack
    • 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
    • Continuous Futures (Brent, WTI)
    • 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
    • Drilling Intelligence (Public)
    • 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

Demo API (No Authentication)

Status: ✅ Available | ⚡ Real-time | 🆓 No API Key Required

Try the API instantly without signing up. Perfect for testing and exploring.

GET/v1/demo/prices

Overview

The demo endpoint provides instant access to real-time commodity prices without authentication. Use it to:

  • Test your integration before signing up
  • Explore API responses in the browser
  • Build quick prototypes

Limitations

FeatureDemo APIAuthenticated API
Rate Limit25/day per IP (see the three lanes below)Up to 100k+/month
Codes per call20 (?codes=A,B,C, billed as one request)20
Commodities37 free-tier codes220+
Historical Data❌✅
WebSocket❌✅ (Premium)

Three limits apply, in this order

All three are keyed on your IP address. The first one you exceed is the one that refuses you, and the two lanes return different 429 bodies — branch on the body, not on the status.

LaneLimitEnforced by429 shape
Per-minute burst10 requests/minute for keyless /v1/* requests — plan against this oneRequest middleware, before the demo endpoint runsTop-level error_code: "RATE_LIMIT_EXCEEDED", no demo fields, no X-Demo-Mode. Retry-After is the seconds left in the minute, and X-RateLimit-Limit reports whichever lane tripped (see below)
Hourly burst guard30 requests/hourThe demo endpointerror.code: "DEMO_RATE_LIMIT_EXCEEDED" (below)
Daily cap (binding)25 requests/dayThe demo endpointerror.code: "DEMO_RATE_LIMIT_EXCEEDED" (below)

The daily cap of 25 is the binding one by design — 30/hour is only a burst guard above it. The per-minute middleware lane is not demo-specific: it applies to every keyless request, so a tight loop trips it long before the hourly limit, and the response carries none of the demo's advice fields.

Treat the per-minute headers as "whichever lane tripped", not as a fixed number. There are two middleware rules and a keyless /v1 request matches both: a 10/minute rule for keyless /v1/* and a broader 20/minute per-IP rule for keyless traffic generally. The first rule you exceed is the one that refuses you, so requests 11–20 within a minute report X-RateLimit-Limit: 10 while a caller already past 20 reports 20 (observed live on 2026-09-11 from a deep burst). 10 requests/minute is the ceiling to design against.

The demo tier exists for evaluation; anything that needs more than 25 calls a day wants the free API key, which allows 50 requests per day and moves you onto the much more generous authenticated lanes.

Available Commodities

37 free-tier codes are available without authentication. A call with no parameters returns the first 20 of them (the per-request batch cap); name the ones you want with ?codes=A,B,C — up to 20 codes in one call, counted as a single request:

BRENT_CRUDE_USD, WTI_USD, NATURAL_GAS_USD, GOLD_USD, EUR_USD, GBP_USD, HEATING_OIL_USD, GASOLINE_USD, DIESEL_USD, OPEC_BASKET_USD, DUBAI_CRUDE_USD, BASRAH_MEDIUM_USD, BASRAH_HEAVY_USD, AZERI_LIGHT_USD, URALS_CRUDE_USD, WCS_CRUDE_USD, GASOLINE_RBOB_USD, ULSD_DIESEL_USD, DIESEL_RETAIL_USD, SILVER_USD, GOLD_AM_USD, GOLD_PM_USD, SILVER_FIX_USD, PLATINUM_USD, PALLADIUM_USD, USD_NOK, EUR_NOK, NATURAL_GAS_GBP, COAL_USD, NEWCASTLE_COAL_USD, COKING_COAL_USD, CAPP_COAL_USD, PRB_COAL_USD, ILLINOIS_COAL_USD, EU_CARBON_EUR, UK_CARBON_GBP, PROPANE_MONT_BELVIEU_USD

Requesting more than 20 codes in one call returns 400 with "Too many commodity codes requested (max: 20, requested: N)" — the same cap the authenticated API enforces. Premium codes (gas hubs, JKM, jet fuel, futures) are ignored in batch calls and return 403 PREMIUM_COMMODITY on the single-code endpoint.

Response

{
  "status": "success",
  "data": {
    "prices": [
      {
        "code": "NATURAL_GAS_USD",
        "name": "Natural Gas (Henry Hub)",
        "price": 5.34,
        "currency": "USD",
        "updated_at": "2026-01-22T13:43:16Z",
        "change_24h": 7.04,
        "source": "OilPriceAPI"
      }
    ],
    "meta": {
      "demo_mode": true,
      "rate_limit": "30 requests per hour and 25 per day, per IP",
      "rate_limits": {
        "per_hour": 30,
        "per_day": 25,
        "scope": "per IP address, no API key required"
      },
      "max_codes_per_request": 20
    }
  }
}

Response Fields

FieldTypeDescription
codestringCommodity identifier
namestringHuman-readable commodity name
pricenumberCurrent spot price
currencystringPrice currency (usually USD)
updated_atstringISO 8601 timestamp of last update
change_24hnumberPercentage change from 24 hours ago (e.g., 7.04 = +7.04%)
sourcestringAlways "OilPriceAPI" for demo

change_24h is a percentage

The change_24h field contains the percentage change from 24 hours ago, not the absolute dollar change. For example, 7.04 means the price increased by 7.04% in the last 24 hours.

Examples

# Get all demo prices
curl https://api.oilpriceapi.com/v1/demo/prices

# Get specific commodity (demo only supports free-tier commodities)
curl https://api.oilpriceapi.com/v1/demo/prices/WTI_USD
// JavaScript - No API key needed!
const response = await fetch("https://api.oilpriceapi.com/v1/demo/prices");
const data = await response.json();

data.data.prices.forEach((commodity) => {
  const changeDir = commodity.change_24h >= 0 ? "↑" : "↓";
  console.log(
    `${commodity.name}: $${commodity.price} ${changeDir}${Math.abs(commodity.change_24h)}%`,
  );
});
# Python - No API key needed!
import requests

response = requests.get('https://api.oilpriceapi.com/v1/demo/prices')
data = response.json()

for commodity in data['data']['prices']:
    change_dir = '↑' if commodity['change_24h'] >= 0 else '↓'
    print(f"{commodity['name']}: ${commodity['price']} {change_dir}{abs(commodity['change_24h'])}%")

Rate Limit Headers

A demo response served by the endpoint — that is, one that got past the per-minute middleware lane — carries both demo windows (header names verified against a live response, 2026-09-11; HTTP/2 delivers them lowercase):

x-ratelimit-limit: 30
x-ratelimit-remaining: 12
x-ratelimit-reset: 1789167599
x-ratelimit-limit-hour: 30
x-ratelimit-remaining-hour: 12
x-ratelimit-limit-day: 25
x-ratelimit-remaining-day: 4
x-ratelimit-reset-day: 1789171199
x-demo-mode: true

X-RateLimit-Remaining (the standard header) always reports the binding allowance — the smaller of the hourly and daily remainders — so a client that reads only the standard header is never told it has calls left that it does not have. On these responses X-RateLimit-Limit echoes the hourly limit (30); read X-RateLimit-Limit-Day / X-RateLimit-Remaining-Day for the binding daily window. A 429 from the per-minute middleware lane sets X-RateLimit-Limit to whichever rule tripped (10 or 20, as above) and sends none of the -Hour / -Day headers, so treat the presence of X-Demo-Mode as the signal that you are reading demo counters.

Rate Limit Exceeded (429)

When the hourly or daily demo window is exhausted, the response is 429 with Retry-After set and a machine-readable body. This is an abridged capture of a real 2026-09-11 response — the plans block, the rest of what_to_do, and the UTM parameters on the URLs are omitted for length:

{
  "status": "fail",
  "error": {
    "code": "DEMO_RATE_LIMIT_EXCEEDED",
    "message": "Demo limit reached: 25 requests per day from this IP (the hourly burst limit is 30). No API key is needed to use the demo — this limit exists so it stays available to everyone.",
    "limits": {
      "per_hour": 30,
      "per_day": 25,
      "scope": "per IP address, no API key required"
    },
    "retry_after": 5560,
    "what_to_do": [
      "Poll less often. Measured on our own price history: WTI_USD changes about every 24 minutes. Asking more frequently than that returns the value you already have.",
      "Batch your codes. Up to 20 codes in one request count as a SINGLE request, on the demo and on the authenticated API alike, so you never need one request per code. …"
    ],
    "free_api_key": {
      "requests_per_day": 50,
      "cost": "free, no card required",
      "signup_url": "https://www.oilpriceapi.com/signup"
    },
    "documentation_url": "https://docs.oilpriceapi.com"
  }
}

The body also carries update_frequency (measured change cadence for the codes you asked for) and a plans block sized from your IP's observed volume. The 429 sets Cache-Control: no-store and X-RateLimit-Remaining: 0; honor Retry-After before retrying.

A 429 from the per-minute middleware lane looks nothing like this — it has no status or error.code, carrying instead a top-level error: "Rate limit exceeded" with error_code: "RATE_LIMIT_EXCEEDED", a retry_after of at most 60 seconds, and an upgrade block. If you are retrying automatically, read error_code first: a RATE_LIMIT_EXCEEDED clears within the minute, while DEMO_RATE_LIMIT_EXCEEDED may not clear until tomorrow.

Ready for More?

Sign up for free to access:

  • Broad commodity catalog; exact access varies by dataset and plan
  • Historical data
  • Higher rate limits
  • WebSocket streaming
Last Updated: 9/11/26, 11:08 PM
Prev
Price Utility Endpoints
Next
Natural Gas Intelligence