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

JKM LNG

Japan/Korea Marker (JKM) LNG futures, the primary pricing benchmark for Asian liquefied natural gas markets.

API Field: JKM_LNG_USD
Unit: MMBtu
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

8 coal price endpoints: US spot markets (EIA weekly), international futures (12-min updates), and NYMEX historical archives covering thermal and metallurgical coal worldwide.

API Field: NEWCASTLE_COAL_USD
Unit: MT
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

VLSFO Marine Fuel

Very Low Sulfur Fuel Oil Singapore benchmark price, IMO 2020 compliant marine fuel for commercial shipping. For port-specific bunker prices, use the /v1/bunker-fuels API.

API Field: VLSFO_USD
Unit: MT
Endpoint: /health

Marine Gas Oil 0.5%S

Marine Gas Oil Singapore benchmark price with 0.5% sulfur content, compliant with IMO 2020 emission standards. For port-specific bunker prices, use the /v1/bunker-fuels API.

API Field: MGO_05S_USD
Unit: MT
Endpoint: /health

Heavy Fuel Oil 380

Heavy Fuel Oil with 380 cSt viscosity, traditional marine bunker fuel for large vessels.

API Field: HFO_380_USD
Unit: MT
Endpoint: /health

Heavy Fuel Oil 180

Heavy Fuel Oil with 180 cSt viscosity, medium-grade marine bunker fuel for shipping.

API Field: HFO_180_USD
Unit: MT
Endpoint: /health

Tapis Crude Oil

Malaysian Tapis Crude Oil - Light Sweet Asian benchmark oil used for pricing in Southeast Asia.

API Field: TAPIS_CRUDE_USD
Unit: barrel
Endpoint: /health

Western Canadian Select

Western Canadian Select heavy crude oil, the primary Canadian oil benchmark.

API Field: WCS_CRUDE_USD
Unit: barrel
Endpoint: /health

Urals Crude Oil

Russian Urals crude oil, the primary Russian export grade and Eastern European benchmark.

API Field: URALS_CRUDE_USD
Unit: barrel
Endpoint: /health

Diesel (Gulf Coast)

U.S. Gulf Coast Ultra-Low Sulfur No 2 Diesel spot price, critical for transportation and logistics.

API Field: DIESEL_USD
Unit: gallon
Endpoint: /health

ULSD Diesel (NY Harbor)

Ultra Low Sulfur No 2 Diesel spot price FOB New York Harbor, the NYMEX delivery standard.

API Field: ULSD_DIESEL_USD
Unit: gallon
Endpoint: /health

Jet Fuel

Kerosene-type jet fuel spot price, essential for aviation industry fuel costs and planning.

API Field: JET_FUEL_USD
Unit: gallon
Endpoint: /health

Ethanol

Ethanol fuel pricing, renewable biofuel component for gasoline blending.

API Field: ETHANOL_USD
Unit: gallon
Endpoint: /health

EU Carbon Allowances

European Union Emissions Trading System (EU ETS) carbon allowance pricing.

API Field: EU_CARBON_EUR
Unit: tCO2
Endpoint: /health

International Rig Count

Monthly active drilling rig count for international markets outside North America, sourced from Baker Hughes.

API Field: INTERNATIONAL_RIG_COUNT
Unit: rigs
Endpoint: /health

US Rig Count

Weekly active drilling rig count for the United States from Baker Hughes, the industry standard for tracking US drilling activity across all major basins.

API Field: US_RIG_COUNT
Unit: rigs
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

Frequently Asked Questions

How do I install the JavaScript/Node.js SDK?

Install using npm: npm install oilpriceapi or yarn: yarn add oilpriceapi. Works with Node.js 14+ and all modern browsers. TypeScript definitions included.

Does this work with TypeScript?

Yes! The SDK includes full TypeScript support with type definitions. Get autocomplete, type checking, and IntelliSense in VS Code. All API responses are fully typed for type safety.

Can I use this in React, Vue, or Angular?

Absolutely! The SDK works with all JavaScript frameworks including React, Vue, Angular, Svelte, and Next.js. Includes React hooks for easy integration. Works in both browser and Node.js environments.

How do I handle errors and retries?

The SDK uses Promise-based error handling. Catch errors with try/catch or .catch(). Built-in retry logic with exponential backoff. Custom error types: APIError, AuthError, RateLimitError.

Does this support async/await and Promises?

Yes! All SDK methods return Promises and support async/await syntax. Perfect for modern JavaScript applications. Also supports callbacks for backward compatibility.

Ready to Start Building?

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