How to Add Real-Time Oil Prices to Your Oilfield Software [Developer Guide]
Building software for the oil and gas industry? Your users expect real-time oil prices alongside their operational data. This developer guide shows you how to integrate crude oil price data into your oilfield software—whether you're building drilling optimization tools, production dashboards, or well economics calculators.
Why Oilfield Software Needs Price Data
Every E&P operator, drilling contractor, and oilfield service company makes decisions influenced by commodity prices:
| Application Type | How Price Data Adds Value |
|---|---|
| Production dashboards | Show revenue at current strip prices |
| Well economics | Real-time NPV/IRR calculations |
| Drilling software | Activity forecasting based on prices |
| Field planning | Budget vs. actual comparisons |
| Investor reporting | Mark-to-market portfolio values |
The Business Case
Your customers already check oil prices constantly. By embedding price data in your software:
- Increased stickiness: Users stay in your app instead of switching to Bloomberg
- Better decisions: Operational and financial data in one place
- Premium feature: Justify higher pricing tiers
- Competitive advantage: Differentiate from competitors
Quick Start: Your First API Call
Get a Brent crude price in under 5 minutes:
1. Get Your API Key
Sign up at oilpriceapi.com/signup and copy your API key from the dashboard.
2. Make Your First Request
curl "https://api.oilpriceapi.com/v1/prices/latest?by_code=BRENT_CRUDE_USD" \
-H "Authorization: Token YOUR_API_KEY"
3. Parse the Response
{
"status": "success",
"data": {
"price": 76.85,
"formatted": "$76.85",
"currency": "USD",
"code": "BRENT_CRUDE_USD",
"name": "Brent Crude Oil",
"unit": "barrel",
"created_at": "2026-01-30T15:30:00.000Z",
"change": 0.42,
"change_percent": 0.55
}
}
That's it. You now have real-time Brent crude pricing.
Available Commodity Codes
OilPriceAPI covers the benchmarks your oilfield customers need:
Crude Oil Benchmarks
| Code | Description | Use Case |
|---|---|---|
BRENT_CRUDE_USD | Brent Crude (ICE) | International benchmark |
WTI_CRUDE_USD | West Texas Intermediate | US onshore operations |
OPEC_BASKET_USD | OPEC Reference Basket | Global context |
LOUISIANA_LIGHT_USD | Louisiana Light Sweet | Gulf Coast operations |
Natural Gas
| Code | Description | Use Case |
|---|---|---|
NATURAL_GAS_USD | Henry Hub | US gas production |
DUTCH_TTF_EUR | Dutch TTF | European gas |
UK_NATURAL_GAS_GBP | NBP | UK gas operations |
Refined Products
| Code | Description | Use Case |
|---|---|---|
HEATING_OIL_USD | No. 2 Heating Oil | Diesel proxy |
GASOLINE_USD | RBOB Gasoline | Product spread analysis |
Supplementary Data (Energy Intelligence)
| Endpoint | Description | Use Case |
|---|---|---|
/ei/rig_counts | Baker Hughes rig count | Drilling activity |
/ei/oil_inventories | EIA weekly storage | Supply context |
/ei/drilling_productivities | DUC wells by basin | Production forecasts |
Integration Patterns
Pattern 1: Simple Price Display
Display current prices with caching to minimize API calls:
import requests
from functools import lru_cache
import time
class OilPriceClient:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = "https://api.oilpriceapi.com/v1"
self.headers = {"Authorization": f"Token {api_key}"}
@lru_cache(maxsize=100)
def get_price(self, code, cache_key=None):
"""Get price with 5-minute cache."""
response = requests.get(
f"{self.base_url}/prices/latest",
params={"by_code": code},
headers=self.headers
)
return response.json()["data"]
def get_cached_price(self, code):
"""Return cached price, refreshing every 5 minutes."""
cache_key = int(time.time() // 300) # New key every 5 min
return self.get_price(code, cache_key)
# Usage in your application
client = OilPriceClient("YOUR_API_KEY")
def render_price_widget():
brent = client.get_cached_price("BRENT_CRUDE_USD")
wti = client.get_cached_price("WTI_CRUDE_USD")
return {
"brent": {"price": brent["price"], "change": brent["change_percent"]},
"wti": {"price": wti["price"], "change": wti["change_percent"]}
}
Pattern 2: Revenue Calculator
Calculate well revenue at current strip prices:
class WellEconomics:
def __init__(self, api_key):
self.client = OilPriceClient(api_key)
def calculate_revenue(self, daily_oil_bbls, daily_gas_mcf):
"""Calculate daily revenue at current prices."""
oil_price = self.client.get_cached_price("WTI_CRUDE_USD")["price"]
gas_price = self.client.get_cached_price("NATURAL_GAS_USD")["price"]
oil_revenue = daily_oil_bbls * oil_price
gas_revenue = daily_gas_mcf * (gas_price / 10) # $/MMBtu to $/Mcf
return {
"oil_price": oil_price,
"gas_price": gas_price,
"daily_oil_revenue": round(oil_revenue, 2),
"daily_gas_revenue": round(gas_revenue, 2),
"total_daily_revenue": round(oil_revenue + gas_revenue, 2),
"monthly_estimate": round((oil_revenue + gas_revenue) * 30, 2)
}
def calculate_npv(self, production_profile, discount_rate=0.10):
"""Calculate NPV using current prices."""
current_price = self.client.get_cached_price("WTI_CRUDE_USD")["price"]
npv = 0
for month, production_bbls in enumerate(production_profile):
revenue = production_bbls * current_price
discount_factor = 1 / (1 + discount_rate / 12) ** month
npv += revenue * discount_factor
return round(npv, 2)
# Usage
economics = WellEconomics("YOUR_API_KEY")
revenue = economics.calculate_revenue(daily_oil_bbls=150, daily_gas_mcf=500)
print(f"Daily Revenue: ${revenue['total_daily_revenue']:,.2f}")
Pattern 3: Production Dashboard with Historical Context
Show current production value with price trend:
def get_dashboard_data(api_key, daily_production_bbls):
"""Get production value with 30-day price context."""
client = OilPriceClient(api_key)
# Current price
current = client.get_cached_price("WTI_CRUDE_USD")
# Historical prices
response = requests.get(
f"{client.base_url}/prices/past_month",
params={"by_code": "WTI_CRUDE_USD", "interval": "1d"},
headers=client.headers
)
history = response.json()["data"]["prices"]
# Calculate metrics
prices = [p["price"] for p in history]
avg_30d = sum(prices) / len(prices)
high_30d = max(prices)
low_30d = min(prices)
return {
"current_price": current["price"],
"current_change": current["change_percent"],
"price_30d_avg": round(avg_30d, 2),
"price_30d_high": high_30d,
"price_30d_low": low_30d,
"daily_production": daily_production_bbls,
"daily_revenue_current": round(daily_production_bbls * current["price"], 2),
"daily_revenue_avg": round(daily_production_bbls * avg_30d, 2),
"variance_to_avg": round((current["price"] - avg_30d) / avg_30d * 100, 1)
}
Pattern 4: JavaScript Widget for Web Apps
class OilPriceWidget {
constructor(apiKey, containerId) {
this.apiKey = apiKey;
this.baseUrl = "https://api.oilpriceapi.com/v1";
this.container = document.getElementById(containerId);
this.cache = new Map();
}
async fetchPrice(code) {
const cacheKey = `${code}_${Math.floor(Date.now() / 300000)}`;
if (this.cache.has(cacheKey)) {
return this.cache.get(cacheKey);
}
const response = await fetch(
`${this.baseUrl}/prices/latest?by_code=${code}`,
{ headers: { Authorization: `Token ${this.apiKey}` } },
);
const data = await response.json();
this.cache.set(cacheKey, data.data);
return data.data;
}
async render() {
const [brent, wti, gas] = await Promise.all([
this.fetchPrice("BRENT_CRUDE_USD"),
this.fetchPrice("WTI_CRUDE_USD"),
this.fetchPrice("NATURAL_GAS_USD"),
]);
this.container.innerHTML = `
<div class="price-widget">
<div class="price-item">
<span class="label">Brent</span>
<span class="price">$${brent.price.toFixed(2)}</span>
<span class="change ${brent.change >= 0 ? "up" : "down"}">
${brent.change >= 0 ? "+" : ""}${brent.change_percent.toFixed(2)}%
</span>
</div>
<div class="price-item">
<span class="label">WTI</span>
<span class="price">$${wti.price.toFixed(2)}</span>
<span class="change ${wti.change >= 0 ? "up" : "down"}">
${wti.change >= 0 ? "+" : ""}${wti.change_percent.toFixed(2)}%
</span>
</div>
<div class="price-item">
<span class="label">Henry Hub</span>
<span class="price">$${gas.price.toFixed(2)}</span>
<span class="change ${gas.change >= 0 ? "up" : "down"}">
${gas.change >= 0 ? "+" : ""}${gas.change_percent.toFixed(2)}%
</span>
</div>
</div>
`;
}
}
// Initialize and render
const widget = new OilPriceWidget("YOUR_API_KEY", "oil-prices");
widget.render();
setInterval(() => widget.render(), 300000); // Refresh every 5 min
Pattern 5: C#/.NET Integration
For desktop applications or .NET backends:
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
public class OilPriceService
{
private readonly HttpClient _client;
private readonly string _baseUrl = "https://api.oilpriceapi.com/v1";
public OilPriceService(string apiKey)
{
_client = new HttpClient();
_client.DefaultRequestHeaders.Add("Authorization", $"Token {apiKey}");
}
public async Task<PriceData> GetPrice(string code)
{
var response = await _client.GetAsync($"{_baseUrl}/prices/latest?by_code={code}");
var json = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse>(json);
return result.Data;
}
public async Task<decimal> CalculateWellRevenue(decimal dailyOilBbls, decimal dailyGasMcf)
{
var oilPrice = await GetPrice("WTI_CRUDE_USD");
var gasPrice = await GetPrice("NATURAL_GAS_USD");
var oilRevenue = dailyOilBbls * oilPrice.Price;
var gasRevenue = dailyGasMcf * (gasPrice.Price / 10m);
return oilRevenue + gasRevenue;
}
}
public class ApiResponse
{
public string Status { get; set; }
public PriceData Data { get; set; }
}
public class PriceData
{
public decimal Price { get; set; }
public string Code { get; set; }
public decimal Change { get; set; }
public decimal ChangePercent { get; set; }
}
Best Practices
Caching Strategy
Minimize API calls while keeping data fresh:
| Use Case | Cache Duration | Rationale |
|---|---|---|
| Dashboard display | 5 minutes | Balance freshness and efficiency |
| Economics calculations | 15 minutes | Prices don't change that fast |
| Reports/exports | At generation time | Point-in-time accuracy |
| Real-time trading | No cache (WebSocket) | Need tick-by-tick data |
Error Handling
def get_price_with_fallback(client, code, fallback_price=None):
"""Get price with graceful degradation."""
try:
response = client.get_price(code)
return response["price"]
except requests.exceptions.RequestException as e:
# Log the error
logging.warning(f"API request failed: {e}")
# Return cached value if available
if fallback_price:
return fallback_price
# Return None and let UI show "Price unavailable"
return None
Rate Limiting
OilPriceAPI has generous rate limits, but implement exponential backoff:
import time
from functools import wraps
def retry_with_backoff(max_retries=3):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429:
wait = 2 ** attempt
time.sleep(wait)
else:
raise
raise Exception("Max retries exceeded")
return wrapper
return decorator
@retry_with_backoff(max_retries=3)
def fetch_price(client, code):
return client.get_price(code)
Architecture Recommendations
Small Applications (< 100 users)
Your App → OilPriceAPI
Direct API calls with caching. Simple and effective.
Medium Applications (100-1000 users)
Your App → Your Cache Layer → OilPriceAPI
↓
Redis
Add Redis or similar to share cache across instances.
Large Applications (1000+ users)
Your App → Your Price Service → OilPriceAPI
↓ ↓
Database WebSocket
↓
Your Users
Build a dedicated price service that:
- Maintains WebSocket connection for real-time updates
- Stores historical prices in your database
- Serves cached data to your application
Pricing Tiers for Oilfield Software
| Tier | Monthly Requests | Best For |
|---|---|---|
| Free | 1,000 | Development and testing |
| Hobby ($9) | 10,000 | Small apps, MVPs |
| Starter ($29) | 50,000 | Production apps |
| Professional ($79) | 100,000 | Growing apps, WebSocket |
| Business ($149) | 200,000 | Multi-product companies |
| Enterprise | Custom | High-volume platforms |
Most oilfield software companies start at Starter ($29/mo) and grow into Professional as user base expands.
Getting Started
- Sign up at oilpriceapi.com/signup
- Get your free API key (1,000 requests/month to test)
- Copy the code examples above into your project
- Test the integration in development
- Upgrade when you're ready for production
Frequently Asked Questions
How do I handle API downtime in production?
Implement caching and fallbacks. Cache the last known good price with a timestamp. If the API is unavailable, display the cached price with a "Last updated X minutes ago" indicator. Most users prefer seeing slightly stale data over no data.
Can I redistribute price data to my customers?
Yes, with appropriate licensing. Standard plans allow you to display prices within your application to your users. If you're reselling raw data or providing data feeds, contact us about an enterprise license.
What's the data latency?
OilPriceAPI updates prices sub-minute during market hours. For most oilfield applications (dashboards, economics, planning), this is more than sufficient. If you need tick-by-tick data for trading applications, use our WebSocket streaming (Professional tier and above).
Do you support Excel add-ins?
We don't provide a native Excel add-in, but our API works with Excel's Power Query and WEBSERVICE functions. Many users build custom Excel integrations using our REST API.
How do I test without hitting rate limits?
The free tier includes 1,000 requests/month—plenty for development. Use caching in development to avoid unnecessary calls. Our staging environment mirrors production for integration testing.
Related Resources
- API Reference - Complete endpoint documentation
- Python SDK - Official Python client
- JavaScript Examples - Browser and Node.js
- Webhook Configuration - Real-time price alerts
- Baker Hughes Rig Count - Drilling activity data
- Energy Intelligence - Additional industry data