Skip to main content
JavaScript Integration

JavaScript Oil Price API

Integrate real-time oil and commodity prices into your JavaScript applications. Works with Node.js, React, Vue, Angular, and vanilla JavaScript.

Quick Start

1. Install Dependencies (Optional)

npm install axios
npm install node-cache # for Node.js caching
npm install express cors # for Node.js server

2. Get Your API Key

  • Works in browser and Node.js
  • No additional dependencies required
  • 30,000 free requests/month

Basic Integration

// Basic JavaScript integration with fetch API
class OilPriceAPI {
    constructor(apiKey) {
        this.apiKey = apiKey;
        this.baseUrl = 'https://api.oilpriceapi.com';
        this.headers = {
            'Authorization': `Token ${apiKey}`,
            'Content-Type': 'application/json'
        };
    }

    async getBrentPrice() {
        try {
            const response = await fetch(`${this.baseUrl}/prices`, {
                headers: this.headers
            });
            
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            
            return await response.json();
        } catch (error) {
            console.error('Error fetching Brent price:', error);
            throw error;
        }
    }

    async getCommodityHealth() {
        try {
            const response = await fetch(`${this.baseUrl}/health`, {
                headers: this.headers
            });
            
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            
            return await response.json();
        } catch (error) {
            console.error('Error fetching commodity health:', error);
            throw error;
        }
    }

    async getWTIPrice() {
        try {
            const healthData = await this.getCommodityHealth();
            const wtiData = healthData.metrics?.commodity_health?.WTI_USD;
            
            if (wtiData) {
                return {
                    price: wtiData.latest_price / 100, // Convert from cents
                    timestamp: wtiData.last_update,
                    currency: 'USD',
                    unit: 'barrel'
                };
            }
            return null;
        } catch (error) {
            console.error('Error fetching WTI price:', error);
            throw error;
        }
    }

    async getAllCommodities() {
        try {
            const [brentResponse, healthResponse] = await Promise.all([
                this.getBrentPrice(),
                this.getCommodityHealth()
            ]);

            const commodities = {
                brent: {
                    price: brentResponse.data.price,
                    timestamp: brentResponse.data.timestamp
                }
            };

            const healthData = healthResponse.metrics?.commodity_health || {};
            
            // Extract other commodities from health data
            Object.entries(healthData).forEach(([key, data]) => {
                if (data.latest_price) {
                    const scale = key.includes('EUR_USD') || key.includes('GBP_USD') ? 10000 : 100;
                    commodities[key.toLowerCase()] = {
                        price: data.latest_price / scale,
                        timestamp: data.last_update
                    };
                }
            });

            return commodities;
        } catch (error) {
            console.error('Error fetching all commodities:', error);
            throw error;
        }
    }
}

// Usage example
const api = new OilPriceAPI('YOUR_API_KEY_HERE');

// Get individual prices
api.getBrentPrice()
    .then(data => console.log('Brent:', data.data.price))
    .catch(error => console.error('Error:', error));

// Get all commodities
api.getAllCommodities()
    .then(commodities => {
        console.log('All commodities:', commodities);
    })
    .catch(error => console.error('Error:', error));

React Integration

Complete React component with custom hook for state management:

import React, { useState, useEffect } from 'react';

// Custom hook for oil price data
function useOilPrices(apiKey) {
    const [prices, setPrices] = useState({});
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        const api = new OilPriceAPI(apiKey);
        
        const fetchPrices = async () => {
            try {
                setLoading(true);
                const commodities = await api.getAllCommodities();
                setPrices(commodities);
                setError(null);
            } catch (err) {
                setError(err.message);
            } finally {
                setLoading(false);
            }
        };

        fetchPrices();
        
        // Update every 5 minutes
        const interval = setInterval(fetchPrices, 5 * 60 * 1000);
        
        return () => clearInterval(interval);
    }, [apiKey]);

    return { prices, loading, error };
}

// React component for displaying oil prices
function OilPriceDashboard({ apiKey }) {
    const { prices, loading, error } = useOilPrices(apiKey);

    if (loading) {
        return (
            <div className="flex items-center justify-center p-8">
                <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
                <span className="ml-2">Loading prices...</span>
            </div>
        );
    }

    if (error) {
        return (
            <div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
                <strong>Error:</strong> {error}
            </div>
        );
    }

    return (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            {Object.entries(prices).map(([commodity, data]) => (
                <div key={commodity} className="bg-white border border-gray-200 rounded-lg p-4 shadow">
                    <h3 className="font-semibold text-lg capitalize mb-2">
                        {commodity.replace('_', ' ')}
                    </h3>
                    <div className="text-2xl font-bold text-blue-600">
                        ${typeof data.price === 'number' ? data.price.toFixed(2) : data.price}
                    </div>
                    <div className="text-sm text-gray-500 mt-1">
                        Updated: {new Date(data.timestamp).toLocaleTimeString()}
                    </div>
                </div>
            ))}
        </div>
    );
}

// Usage in your React app
function App() {
    return (
        <div className="p-8">
            <h1 className="text-3xl font-bold mb-8">Live Oil Prices</h1>
            <OilPriceDashboard apiKey="YOUR_API_KEY_HERE" />
        </div>
    );
}

export default App;

Node.js Server

Express server with caching and error handling:

// Node.js server implementation with Express
const express = require('express');
const cors = require('cors');
const NodeCache = require('node-cache');

const app = express();
const cache = new NodeCache({ stdTTL: 300 }); // 5 minute cache

app.use(cors());
app.use(express.json());

class OilPriceService {
    constructor(apiKey) {
        this.apiKey = apiKey;
        this.baseUrl = 'https://api.oilpriceapi.com';
        this.headers = {
            'Authorization': `Token ${apiKey}`,
            'Content-Type': 'application/json'
        };
    }

    async fetchWithTimeout(url, options, timeout = 5000) {
        const controller = new AbortController();
        const id = setTimeout(() => controller.abort(), timeout);

        try {
            const response = await fetch(url, {
                ...options,
                signal: controller.signal
            });
            clearTimeout(id);
            return response;
        } catch (error) {
            clearTimeout(id);
            throw error;
        }
    }

    async getBrentPrice() {
        const response = await this.fetchWithTimeout(
            `${this.baseUrl}/prices`,
            { headers: this.headers }
        );
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return await response.json();
    }

    async getCommodityHealth() {
        const response = await this.fetchWithTimeout(
            `${this.baseUrl}/health`,
            { headers: this.headers }
        );
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return await response.json();
    }

    async getAllPrices() {
        try {
            const [brentData, healthData] = await Promise.all([
                this.getBrentPrice(),
                this.getCommodityHealth()
            ]);

            const prices = {
                brent_crude: {
                    price: brentData.data.price,
                    timestamp: brentData.data.timestamp,
                    unit: 'barrel'
                }
            };

            const commodities = healthData.metrics?.commodity_health || {};
            
            // Process each commodity
            Object.entries(commodities).forEach(([key, data]) => {
                if (data.latest_price) {
                    let scale = 100;
                    if (key.includes('EUR_USD') || key.includes('GBP_USD')) {
                        scale = 10000; // Currency pairs
                    }
                    
                    prices[key.toLowerCase()] = {
                        price: data.latest_price / scale,
                        timestamp: data.last_update,
                        unit: this.getUnit(key)
                    };
                }
            });

            return {
                status: 'success',
                data: prices,
                cached_at: new Date().toISOString()
            };
        } catch (error) {
            throw new Error(`Failed to fetch prices: ${error.message}`);
        }
    }

    getUnit(commodityKey) {
        const units = {
            'WTI_USD': 'barrel',
            'NATURAL_GAS_USD': 'MMBtu',
            'GOLD_USD': 'ounce',
            'EUR_USD': 'USD',
            'GBP_USD': 'USD'
        };
        return units[commodityKey] || 'unit';
    }
}

// Initialize service
const priceService = new OilPriceService(process.env.OIL_PRICE_API_KEY);

// Middleware to ensure API key is set
const requireApiKey = (req, res, next) => {
    if (!process.env.OIL_PRICE_API_KEY) {
        return res.status(500).json({
            error: 'API key not configured'
        });
    }
    next();
};

// Routes
app.get('/api/prices', requireApiKey, async (req, res) => {
    try {
        // Check cache first
        const cachedPrices = cache.get('all_prices');
        if (cachedPrices) {
            return res.json({
                ...cachedPrices,
                cached: true
            });
        }

        // Fetch fresh data
        const prices = await priceService.getAllPrices();
        
        // Cache the results
        cache.set('all_prices', prices);
        
        res.json(prices);
    } catch (error) {
        console.error('Error fetching prices:', error);
        res.status(500).json({
            status: 'error',
            message: error.message
        });
    }
});

app.get('/api/prices/:commodity', requireApiKey, async (req, res) => {
    try {
        const { commodity } = req.params;
        
        // Get all prices (from cache or API)
        let allPrices = cache.get('all_prices');
        if (!allPrices) {
            allPrices = await priceService.getAllPrices();
            cache.set('all_prices', allPrices);
        }

        const commodityData = allPrices.data[commodity.toLowerCase()];
        
        if (!commodityData) {
            return res.status(404).json({
                status: 'error',
                message: `Commodity '${commodity}' not found`
            });
        }

        res.json({
            status: 'success',
            commodity: commodity,
            data: commodityData
        });
    } catch (error) {
        console.error('Error fetching commodity price:', error);
        res.status(500).json({
            status: 'error',
            message: error.message
        });
    }
});

app.get('/health', (req, res) => {
    const cacheKeys = cache.keys();
    res.json({
        status: 'healthy',
        cache_entries: cacheKeys.length,
        uptime: process.uptime(),
        memory_usage: process.memoryUsage()
    });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

Vue.js Component

Vue 3 component with Composition API:

<!-- Vue.js component for oil prices -->
<template>
  <div class="oil-prices-dashboard">
    <div class="header">
      <h1>Live Oil Prices</h1>
      <div class="last-updated" v-if="lastUpdated">
        Last updated: {{ formatTime(lastUpdated) }}
      </div>
    </div>

    <div v-if="loading" class="loading">
      <div class="spinner"></div>
      <p>Loading prices...</p>
    </div>

    <div v-if="error" class="error">
      <p>{{ error }}</p>
      <button @click="fetchPrices" class="retry-btn">Retry</button>
    </div>

    <div v-if="!loading && !error" class="prices-grid">
      <div 
        v-for="(data, commodity) in prices" 
        :key="commodity"
        class="price-card"
        :class="{ 'price-updated': recentlyUpdated.includes(commodity) }"
      >
        <h3>{{ formatCommodityName(commodity) }}</h3>
        <div class="price">
          ${{ formatPrice(data.price) }}
        </div>
        <div class="unit">{{ data.unit }}</div>
        <div class="timestamp">
          {{ formatTime(data.timestamp) }}
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, onMounted, onUnmounted } from 'vue';

export default {
  name: 'OilPricesDashboard',
  props: {
    apiKey: {
      type: String,
      required: true
    }
  },
  setup(props) {
    const prices = ref({});
    const loading = ref(true);
    const error = ref(null);
    const lastUpdated = ref(null);
    const recentlyUpdated = ref([]);
    let updateInterval = null;

    class OilPriceAPI {
      constructor(apiKey) {
        this.apiKey = apiKey;
        this.baseUrl = 'https://api.oilpriceapi.com';
        this.headers = {
          'Authorization': `Token ${apiKey}`,
          'Content-Type': 'application/json'
        };
      }

      async getAllCommodities() {
        try {
          const [brentResponse, healthResponse] = await Promise.all([
            fetch(`${this.baseUrl}/prices`, { headers: this.headers }),
            fetch(`${this.baseUrl}/health`, { headers: this.headers })
          ]);

          if (!brentResponse.ok || !healthResponse.ok) {
            throw new Error('Failed to fetch data');
          }

          const brentData = await brentResponse.json();
          const healthData = await healthResponse.json();

          const commodities = {
            brent_crude: {
              price: brentData.data.price,
              timestamp: brentData.data.timestamp,
              unit: 'barrel'
            }
          };

          const healthCommodities = healthData.metrics?.commodity_health || {};
          
          Object.entries(healthCommodities).forEach(([key, data]) => {
            if (data.latest_price) {
              const scale = key.includes('EUR_USD') || key.includes('GBP_USD') ? 10000 : 100;
              commodities[key.toLowerCase()] = {
                price: data.latest_price / scale,
                timestamp: data.last_update,
                unit: this.getUnit(key)
              };
            }
          });

          return commodities;
        } catch (err) {
          throw new Error(`API Error: ${err.message}`);
        }
      }

      getUnit(key) {
        const units = {
          'WTI_USD': 'barrel',
          'NATURAL_GAS_USD': 'MMBtu',
          'GOLD_USD': 'ounce',
          'EUR_USD': 'USD',
          'GBP_USD': 'USD'
        };
        return units[key] || 'unit';
      }
    }

    const api = new OilPriceAPI(props.apiKey);

    const fetchPrices = async () => {
      try {
        loading.value = true;
        error.value = null;
        
        const newPrices = await api.getAllCommodities();
        
        // Check for price changes
        const updated = [];
        Object.keys(newPrices).forEach(commodity => {
          if (prices.value[commodity] && 
              prices.value[commodity].price !== newPrices[commodity].price) {
            updated.push(commodity);
          }
        });
        
        prices.value = newPrices;
        lastUpdated.value = new Date();
        recentlyUpdated.value = updated;
        
        // Clear update indicators after 3 seconds
        setTimeout(() => {
          recentlyUpdated.value = [];
        }, 3000);
        
      } catch (err) {
        error.value = err.message;
      } finally {
        loading.value = false;
      }
    };

    const formatPrice = (price) => {
      return typeof price === 'number' ? price.toFixed(2) : price;
    };

    const formatCommodityName = (commodity) => {
      return commodity.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
    };

    const formatTime = (timestamp) => {
      return new Date(timestamp).toLocaleString();
    };

    onMounted(() => {
      fetchPrices();
      // Update every 5 minutes
      updateInterval = setInterval(fetchPrices, 5 * 60 * 1000);
    });

    onUnmounted(() => {
      if (updateInterval) {
        clearInterval(updateInterval);
      }
    });

    return {
      prices,
      loading,
      error,
      lastUpdated,
      recentlyUpdated,
      fetchPrices,
      formatPrice,
      formatCommodityName,
      formatTime
    };
  }
};
</script>

<style scoped>
.oil-prices-dashboard {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.header {
  text-align: center;
  margin-bottom: 30px;
}

.header h1 {
  font-size: 2.5rem;
  color: #333;
  margin-bottom: 10px;
}

.last-updated {
  color: #666;
  font-size: 0.9rem;
}

.loading {
  text-align: center;
  padding: 50px;
}

.spinner {
  border: 4px solid #f3f3f3;
  border-top: 4px solid #3498db;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  animation: spin 1s linear infinite;
  margin: 0 auto 20px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.error {
  text-align: center;
  padding: 30px;
  color: #e74c3c;
}

.retry-btn {
  background: #3498db;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 5px;
  cursor: pointer;
  margin-top: 10px;
}

.prices-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

.price-card {
  background: white;
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 20px;
  text-align: center;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  transition: all 0.3s ease;
}

.price-card.price-updated {
  border-color: #2ecc71;
  box-shadow: 0 0 10px rgba(46, 204, 113, 0.3);
  animation: pulse 1s ease-in-out;
}

@keyframes pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.05); }
  100% { transform: scale(1); }
}

.price-card h3 {
  margin: 0 0 15px 0;
  color: #333;
  font-size: 1.2rem;
}

.price {
  font-size: 2rem;
  font-weight: bold;
  color: #2c3e50;
  margin-bottom: 5px;
}

.unit {
  color: #7f8c8d;
  margin-bottom: 10px;
}

.timestamp {
  font-size: 0.8rem;
  color: #95a5a6;
}
</style>

Available Commodities

Brent Crude Oil

North Sea Brent crude oil, the global benchmark for oil pricing representing ~60% of internationally traded crude oil.

API Field: BRENT_CRUDE_USD
Unit: barrel
Endpoint: /prices

WTI Crude Oil

West Texas Intermediate crude oil, the primary benchmark for North American oil markets and NYMEX futures.

API Field: WTI_USD
Unit: barrel
Endpoint: /health

Dubai Crude Oil

Dubai crude oil benchmark for Middle Eastern crude oil pricing and Asian markets.

API Field: DUBAI_CRUDE_USD
Unit: barrel
Endpoint: /health

Natural Gas

NYMEX Henry Hub natural gas futures, the primary pricing benchmark for North American natural gas markets.

API Field: NATURAL_GAS_USD
Unit: MMBtu
Endpoint: /health

Natural Gas (UK)

UK natural gas pricing in British pence per therm.

API Field: NATURAL_GAS_GBP
Unit: GBp/thm
Endpoint: /health

Dutch TTF Gas

Dutch Title Transfer Facility (TTF) natural gas futures, the European gas pricing benchmark.

API Field: DUTCH_TTF_EUR
Unit: EUR/MWh
Endpoint: /health

Gasoline RBOB

Reformulated Blendstock for Oxygenate Blending (RBOB) gasoline futures.

API Field: GASOLINE_RBOB_USD
Unit: gallon
Endpoint: /health

Heating Oil

No. 2 heating oil futures, a key refined petroleum product for heating and industrial use.

API Field: HEATING_OIL_USD
Unit: gallon
Endpoint: /health

Coal

Coal futures pricing for thermal coal used in power generation.

API Field: COAL_USD
Unit: ton
Endpoint: /health

Gold

Gold futures pricing, a key precious metal and safe-haven asset.

API Field: GOLD_USD
Unit: ounce
Endpoint: /health

EUR/USD

Euro to US Dollar exchange rate, the most traded currency pair globally.

API Field: EUR_USD
Unit: USD
Endpoint: /health

GBP/USD

British Pound to US Dollar exchange rate, also known as "Cable".

API Field: GBP_USD
Unit: USD
Endpoint: /health

Best Practices

Error Handling

  • Always use try/catch with async/await
  • Check response.ok before parsing JSON
  • Implement fallback data for offline scenarios

Performance

  • Cache responses in localStorage/memory
  • Use Promise.all() for parallel requests
  • Implement request debouncing

Ready to Start Building?

Get your free API key and start integrating real-time commodity prices into your JavaScript applications today.