# 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

# 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

# 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

# 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. 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

# 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

# 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