# Historical Prices
Access historical price data for oil and commodity markets with customizable time ranges and intervals.
# Endpoints
GET /v1/prices/past_day Hourly prices for past 24 hours
GET /v1/prices/past_week Daily prices for past 7 days
GET /v1/prices/past_month Daily prices for past 30 days
GET /v1/prices/past_year Weekly prices for past 365 days
# Request Parameters
All historical endpoints support the same query parameters:
Parameter | Type | Required | Description | Example |
---|---|---|---|---|
by_code | string | Yes | Comma-separated commodity codes | WTI_USD,BRENT_CRUDE_USD,NATURAL_GAS_USD |
interval | string | No | Data point interval | 1h , 1d , 1w |
currency | string | No | Convert prices to specified currency | EUR , GBP , JPY |
format | string | No | Response format | json (default), csv |
# Response Format
# Past Day (Hourly Data)
# Past Week/Month/Year
The response format is similar but with different intervals:
{
"status": "success",
"data": {
"WTI": {
"name": "West Texas Intermediate",
"currency": "USD",
"unit": "barrel",
"prices": [
{
"date": "2025-07-18",
"open": 77.90,
"high": 79.20,
"low": 77.50,
"close": 78.45,
"volume": 2854320,
"average": 78.35
},
{
"date": "2025-07-17",
"open": 77.20,
"high": 78.10,
"low": 76.80,
"close": 77.90,
"volume": 2654180,
"average": 77.45
}
// ... more daily data points
],
"summary": {
"period": "week",
"start": "2025-07-11",
"end": "2025-07-18",
"high": 81.30,
"low": 76.20,
"average": 78.75,
"volatility": 2.45
}
}
},
"meta": {
"request_id": "req_week456",
"response_time_ms": 234,
"data_points": 7,
"interval": "1d"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Code Examples
# Data Analysis Examples
# Moving Averages
def calculate_moving_averages(commodity='WTI', periods=[7, 30]):
response = requests.get(
'https://api.oilpriceapi.com/v1/prices/past_year',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
params={'commodities': commodity, 'interval': '1d'}
)
data = response.json()
prices = pd.DataFrame(data['data'][commodity]['prices'])
prices['date'] = pd.to_datetime(prices['date'])
prices.set_index('date', inplace=True)
# Calculate moving averages
for period in periods:
prices[f'MA{period}'] = prices['close'].rolling(window=period).mean()
# Find crossovers
prices['signal'] = 0
prices.loc[prices['MA7'] > prices['MA30'], 'signal'] = 1
prices.loc[prices['MA7'] < prices['MA30'], 'signal'] = -1
return prices
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Price Correlations
async function calculateCorrelations() {
const response = await fetch('https://api.oilpriceapi.com/v1/prices/past_month', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
params: { commodities: 'WTI,BRENT,NATURAL_GAS' }
});
const data = await response.json();
// Extract price arrays
const wtiPrices = data.data.WTI.prices.map(p => p.close);
const brentPrices = data.data.BRENT.prices.map(p => p.close);
// Calculate correlation
const correlation = calculatePearsonCorrelation(wtiPrices, brentPrices);
console.log(`WTI-Brent correlation: ${correlation.toFixed(3)}`);
}
function calculatePearsonCorrelation(x, y) {
const n = x.length;
const sum_x = x.reduce((a, b) => a + b);
const sum_y = y.reduce((a, b) => a + b);
const sum_xy = x.reduce((total, xi, i) => total + xi * y[i], 0);
const sum_x2 = x.reduce((total, xi) => total + xi * xi, 0);
const sum_y2 = y.reduce((total, yi) => total + yi * yi, 0);
const numerator = n * sum_xy - sum_x * sum_y;
const denominator = Math.sqrt((n * sum_x2 - sum_x * sum_x) * (n * sum_y2 - sum_y * sum_y));
return numerator / denominator;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Best Practices
# 1. Choose Appropriate Intervals
// For short-term trading - use hourly data
const shortTerm = await fetch('/v1/prices/past_day?interval=1h');
// For trend analysis - use daily data
const mediumTerm = await fetch('/v1/prices/past_month?interval=1d');
// For long-term investment - use weekly data
const longTerm = await fetch('/v1/prices/past_year?interval=1w');
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2. Handle Large Datasets
# Stream CSV data for large requests
def stream_historical_data(timeframe='past_year'):
with requests.get(
f'https://api.oilpriceapi.com/v1/prices/{timeframe}',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
params={'format': 'csv'},
stream=True
) as response:
response.raise_for_status()
# Process in chunks
for chunk in pd.read_csv(response.raw, chunksize=1000):
process_chunk(chunk)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 3. Implement Caching
class HistoricalPriceCache {
constructor(ttl = 3600000) { // 1 hour TTL
this.cache = new Map();
this.ttl = ttl;
}
getCacheKey(endpoint, params) {
return `${endpoint}:${JSON.stringify(params)}`;
}
async get(endpoint, params) {
const key = this.getCacheKey(endpoint, params);
const cached = this.cache.get(key);
if (cached && Date.now() - cached.timestamp < this.ttl) {
return cached.data;
}
const fresh = await this.fetchData(endpoint, params);
this.cache.set(key, {
data: fresh,
timestamp: Date.now()
});
return fresh;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Rate Limiting
Historical data endpoints have specific rate limits:
Endpoint | Free | Hobby | Professional | Reservoir Mastery |
---|---|---|---|---|
/past_day | 10/hour | 100/hour | 1000/hour | Unlimited |
/past_week | 5/hour | 50/hour | 500/hour | Unlimited |
/past_month | 2/hour | 20/hour | 200/hour | Unlimited |
/past_year | 1/hour | 10/hour | 100/hour | Unlimited |
# Error Handling
async function getHistoricalWithRetry(endpoint, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(`https://api.oilpriceapi.com/v1/prices/${endpoint}`, {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
if (response.status === 429) {
// Rate limited
const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
console.log(`Rate limited. Waiting ${retryAfter}s...`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
} catch (error) {
if (i === maxRetries - 1) throw error;
// Exponential backoff
const delay = Math.min(1000 * Math.pow(2, i), 10000);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Related Resources
- Latest Prices - Current market prices
- Price Streaming - Real-time updates
- Technical Indicators - Calculate RSI, MACD, etc.
- Market Analysis - Advanced analytics