Skip to main content

How to Get Real-Time Oil Prices in Node.js (Complete Tutorial)

15 min read

Learn how to fetch real-time oil prices in Node.js using the official OilPriceAPI SDK. Includes 12+ working JavaScript and TypeScript examples for Express, Next.js, Discord bots, and more. Perfect for trading applications and real-time dashboards.

Why Node.js for Oil Price Data?

Node.js dominates backend development for trading platforms, real-time dashboards, and API integrations. When you need to fetch live oil prices, build energy market monitors, or create automated trading systems, Node's event-driven architecture and async capabilities make it the perfect choice.

Here's why Node.js excels at handling commodity price data:

  • Non-blocking I/O: Handle thousands of concurrent API requests without blocking
  • Real-time capabilities: WebSocket support for live price streams
  • npm ecosystem: 2 million+ packages including trading libraries
  • TypeScript support: Full type safety for financial data
  • Microservices ready: Deploy price feeds as scalable services

What You'll Build

  • ✓ Fetch current WTI, Brent, and natural gas prices
  • ✓ Get historical data for backtesting strategies
  • ✓ Build Express API endpoints serving oil prices
  • ✓ Create Next.js API routes with server-side caching
  • ✓ Real-time price streams with WebSockets
  • ✓ Discord bot with live commodity price commands

Method 1: Official Node.js SDK (Recommended)

The official @oilpriceapi/client package provides a production-ready SDK with TypeScript support, automatic retries, and error handling. Perfect for most use cases.

Step 1: Installation

npm install @oilpriceapi/client

Step 2: Get Your API Key

Sign up at oilpriceapi.com to get your free API key (100 API requests included). Store it in your environment variables.

# .env
OIL_PRICE_API_KEY=your_api_key_here

Step 3: Fetch Current Prices (JavaScript)

const { OilPriceAPIClient } = require('@oilpriceapi/client');

// Initialize client
const client = new OilPriceAPIClient({
  apiKey: process.env.OIL_PRICE_API_KEY
});

// Fetch latest Brent price
async function getOilPrice() {
  try {
    const price = await client.getLatestPrice({
      code: 'BRENT_CRUDE_USD'
    });

    console.log(`Brent Crude: $${price.price}`);
    console.log(`Updated: ${price.createdAt}`);

    return price;
  } catch (error) {
    console.error('Failed to fetch price:', error.message);
  }
}

getOilPrice();

// Output:
// Brent Crude: $82.30
// Updated: 2025-01-15T14:35:22Z

Example 2: TypeScript with Full Type Safety

import { OilPriceAPIClient, Price } from '@oilpriceapi/client';

const client = new OilPriceAPIClient({
  apiKey: process.env.OIL_PRICE_API_KEY!
});

async function getMultiplePrices(): Promise<void> {
  const commodities = [
    'BRENT_CRUDE_USD',
    'WTI_USD',
    'NATURAL_GAS_USD'
  ] as const;

  console.log('Current Energy Prices:');
  console.log('-'.repeat(40));

  for (const code of commodities) {
    const price: Price = await client.getLatestPrice({ code });
    console.log(`${price.name.padEnd(25)} $${price.price.toFixed(2)}`);
  }
}

getMultiplePrices();

// Output:
// Current Energy Prices:
// ----------------------------------------
// Brent Crude Oil          $  82.30
// WTI Crude Oil            $  78.45
// Natural Gas              $   3.12

Example 3: Historical Data

const { OilPriceAPIClient } = require('@oilpriceapi/client');

const client = new OilPriceAPIClient({
  apiKey: process.env.OIL_PRICE_API_KEY
});

async function getHistoricalData() {
  // Get last 30 days of WTI prices
  const endDate = new Date();
  const startDate = new Date();
  startDate.setDate(startDate.getDate() - 30);

  const data = await client.getHistoricalPrices({
    code: 'WTI_USD',
    startDate: startDate.toISOString().split('T')[0],
    endDate: endDate.toISOString().split('T')[0]
  });

  console.log(`WTI Prices - Last 30 Days:`);
  console.log(`Total data points: ${data.data.length}`);

  // Calculate statistics
  const prices = data.data.map(d => d.price);
  const avg = prices.reduce((a, b) => a + b, 0) / prices.length;
  const min = Math.min(...prices);
  const max = Math.max(...prices);

  console.log(`\nStatistics:`);
  console.log(`Average: $${avg.toFixed(2)}`);
  console.log(`Min: $${min.toFixed(2)}`);
  console.log(`Max: $${max.toFixed(2)}`);
  console.log(`Range: $${(max - min).toFixed(2)}`);
}

getHistoricalData();

Example 4: Error Handling

const { OilPriceAPIClient, OilPriceAPIError } = require('@oilpriceapi/client');

const client = new OilPriceAPIClient({
  apiKey: process.env.OIL_PRICE_API_KEY
});

async function safeGetPrice(commodityCode) {
  try {
    const price = await client.getLatestPrice({ code: commodityCode });
    return { success: true, data: price };
  } catch (error) {
    if (error instanceof OilPriceAPIError) {
      // API-specific errors
      if (error.statusCode === 401) {
        console.error('Authentication failed. Check your API key.');
      } else if (error.statusCode === 429) {
        console.error('Rate limit exceeded. Try again later.');
      } else {
        console.error(`API Error: ${error.message}`);
      }
    } else {
      // Network or other errors
      console.error(`Unexpected error: ${error.message}`);
    }

    return { success: false, error: error.message };
  }
}

// Usage
safeGetPrice('BRENT_CRUDE_USD').then(result => {
  if (result.success) {
    console.log(`Price: $${result.data.price}`);
  }
});

SDK Advantages

  • ✓ Full TypeScript support with type definitions
  • ✓ Automatic retry logic with exponential backoff
  • ✓ Built-in error handling and custom exceptions
  • ✓ Request/response logging for debugging
  • ✓ Promise-based and async/await compatible
  • ✓ Actively maintained and updated

Method 2: Direct REST API with Axios

If you prefer direct HTTP requests or need custom request logic, you can use Axios (or native fetch) to call the REST API directly.

Installation

npm install axios dotenv

Example 5: Basic Axios Request

const axios = require('axios');
require('dotenv').config();

const API_KEY = process.env.OIL_PRICE_API_KEY;
const BASE_URL = 'https://api.oilpriceapi.com/v1';

async function fetchOilPrice(commodityCode) {
  try {
    const response = await axios.get(`${BASE_URL}/prices/latest`, {
      headers: {
        'Authorization': `Token ${API_KEY}`,
        'Content-Type': 'application/json'
      },
      params: {
        by_code: commodityCode
      }
    });

    const priceData = response.data.data;
    console.log(`${priceData.name}: $${priceData.price}`);

    return priceData;
  } catch (error) {
    if (error.response) {
      console.error(`API Error [${error.response.status}]: ${error.response.data.message}`);
    } else {
      console.error(`Request failed: ${error.message}`);
    }
  }
}

fetchOilPrice('BRENT_CRUDE_USD');

Example 6: Axios Instance with Interceptors

const axios = require('axios');

// Create reusable Axios instance
const oilPriceAPI = axios.create({
  baseURL: 'https://api.oilpriceapi.com/v1',
  headers: {
    'Authorization': `Token ${process.env.OIL_PRICE_API_KEY}`,
    'Content-Type': 'application/json'
  },
  timeout: 10000 // 10 second timeout
});

// Add request interceptor for logging
oilPriceAPI.interceptors.request.use(
  config => {
    console.log(`[${new Date().toISOString()}] Request: ${config.method.toUpperCase()} ${config.url}`);
    return config;
  },
  error => Promise.reject(error)
);

// Add response interceptor for error handling
oilPriceAPI.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 429) {
      const retryAfter = error.response.headers['retry-after'] || 60;
      console.error(`Rate limited. Retry after ${retryAfter}s`);
    }
    return Promise.reject(error);
  }
);

// Usage
async function getPrice(code) {
  const { data } = await oilPriceAPI.get('/prices/latest', {
    params: { by_code: code }
  });
  return data.data;
}

// Fetch multiple commodities in parallel
async function getAllPrices() {
  const codes = ['WTI_USD', 'BRENT_CRUDE_USD', 'NATURAL_GAS_USD'];

  const prices = await Promise.all(
    codes.map(code => getPrice(code))
  );

  prices.forEach(price => {
    console.log(`${price.name}: $${price.price}`);
  });
}

getAllPrices();

Example 7: Retry Logic

const axios = require('axios');

async function fetchWithRetry(commodityCode, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await axios.get(
        'https://api.oilpriceapi.com/v1/prices/latest',
        {
          headers: {
            'Authorization': `Token ${process.env.OIL_PRICE_API_KEY}`
          },
          params: { by_code: commodityCode },
          timeout: 10000
        }
      );

      return response.data.data;
    } catch (error) {
      console.error(`Attempt ${attempt} failed: ${error.message}`);

      if (attempt < maxRetries) {
        const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
        console.log(`Retrying in ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw new Error(`Failed after ${maxRetries} attempts`);
      }
    }
  }
}

// Usage
fetchWithRetry('WTI_USD')
  .then(price => console.log(`WTI: $${price.price}`))
  .catch(error => console.error(`Failed: ${error.message}`));

Method 3: Real-Time with WebSockets

For real-time applications that need instant price updates, use WebSocket connections to stream live commodity prices.

Installation

npm install ws

Example 8: WebSocket Price Stream

const WebSocket = require('ws');

function connectPriceStream(apiKey, commodities) {
  const ws = new WebSocket('wss://stream.oilpriceapi.com/v1/prices', {
    headers: {
      'Authorization': `Token ${apiKey}`
    }
  });

  ws.on('open', () => {
    console.log('Connected to price stream');

    // Subscribe to commodities
    ws.send(JSON.stringify({
      action: 'subscribe',
      commodities: commodities
    }));
  });

  ws.on('message', (data) => {
    const update = JSON.parse(data);
    console.log(`[${update.timestamp}] ${update.name}: $${update.price}`);
  });

  ws.on('error', (error) => {
    console.error('WebSocket error:', error.message);
  });

  ws.on('close', () => {
    console.log('Connection closed. Reconnecting in 5s...');
    setTimeout(() => {
      connectPriceStream(apiKey, commodities);
    }, 5000);
  });

  return ws;
}

// Usage
const stream = connectPriceStream(
  process.env.OIL_PRICE_API_KEY,
  ['WTI_USD', 'BRENT_CRUDE_USD', 'NATURAL_GAS_USD']
);

// Graceful shutdown
process.on('SIGINT', () => {
  stream.close();
  process.exit();
});

Integration Examples

Example 9: Express API Endpoint

const express = require('express');
const { OilPriceAPIClient } = require('@oilpriceapi/client');

const app = express();
const client = new OilPriceAPIClient({
  apiKey: process.env.OIL_PRICE_API_KEY
});

// Cache prices for 5 minutes
let priceCache = {};
const CACHE_TTL = 5 * 60 * 1000;

app.get('/api/oil-prices/:commodity', async (req, res) => {
  const { commodity } = req.params;
  const cacheKey = commodity.toUpperCase();

  // Check cache
  if (priceCache[cacheKey] &&
      Date.now() - priceCache[cacheKey].timestamp < CACHE_TTL) {
    return res.json({
      cached: true,
      ...priceCache[cacheKey].data
    });
  }

  try {
    const price = await client.getLatestPrice({
      code: cacheKey
    });

    // Update cache
    priceCache[cacheKey] = {
      timestamp: Date.now(),
      data: price
    };

    res.json({
      cached: false,
      ...price
    });
  } catch (error) {
    res.status(500).json({
      error: 'Failed to fetch price',
      message: error.message
    });
  }
});

app.listen(3000, () => {
  console.log('API running on http://localhost:3000');
  console.log('Try: http://localhost:3000/api/oil-prices/WTI_USD');
});

Example 10: Next.js API Route

// app/api/prices/[commodity]/route.ts
import { NextResponse } from 'next/server';
import { OilPriceAPIClient } from '@oilpriceapi/client';

const client = new OilPriceAPIClient({
  apiKey: process.env.OIL_PRICE_API_KEY!
});

export async function GET(
  request: Request,
  { params }: { params: { commodity: string } }
) {
  try {
    const price = await client.getLatestPrice({
      code: params.commodity.toUpperCase()
    });

    return NextResponse.json(price, {
      headers: {
        'Cache-Control': 'public, s-maxage=300, stale-while-revalidate=600'
      }
    });
  } catch (error: any) {
    return NextResponse.json(
      { error: error.message },
      { status: error.statusCode || 500 }
    );
  }
}

// Usage in React component:
// const response = await fetch('/api/prices/WTI_USD');
// const price = await response.json();

Example 11: Discord Bot Price Command

const { Client, GatewayIntentBits } = require('discord.js');
const { OilPriceAPIClient } = require('@oilpriceapi/client');

const discord = new Client({
  intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages]
});

const oilClient = new OilPriceAPIClient({
  apiKey: process.env.OIL_PRICE_API_KEY
});

discord.on('messageCreate', async (message) => {
  if (message.content.startsWith('!price')) {
    const args = message.content.split(' ');
    const commodity = args[1]?.toUpperCase() || 'WTI_USD';

    try {
      const price = await oilClient.getLatestPrice({ code: commodity });

      message.reply({
        embeds: [{
          title: price.name,
          description: `**$${price.price}**`,
          color: 0x0099ff,
          fields: [
            { name: 'Change', value: `${price.change24h > 0 ? '+' : ''}${price.change24h}%`, inline: true },
            { name: 'Updated', value: new Date(price.createdAt).toLocaleString(), inline: true }
          ]
        }]
      });
    } catch (error) {
      message.reply(`Error: ${error.message}`);
    }
  }
});

discord.login(process.env.DISCORD_BOT_TOKEN);

// Usage in Discord:
// !price WTI_USD
// !price BRENT_CRUDE_USD

Example 12: Trading Bot with Cron

const cron = require('node-cron');
const { OilPriceAPIClient } = require('@oilpriceapi/client');

const client = new OilPriceAPIClient({
  apiKey: process.env.OIL_PRICE_API_KEY
});

let lastWTI = null;
let lastBrent = null;

// Run every 5 minutes during trading hours (9 AM - 5 PM ET)
cron.schedule('*/5 9-17 * * 1-5', async () => {
  try {
    const [wti, brent] = await Promise.all([
      client.getLatestPrice({ code: 'WTI_USD' }),
      client.getLatestPrice({ code: 'BRENT_CRUDE_USD' })
    ]);

    const spread = brent.price - wti.price;
    console.log(`[${new Date().toISOString()}] Spread: $${spread.toFixed(2)}`);

    // Trading logic
    if (spread > 4.0 && (!lastWTI || lastWTI < wti.price)) {
      console.log('🔔 SIGNAL: Wide spread - Consider WTI long / Brent short');
      // Execute trade via broker API here
    }

    lastWTI = wti.price;
    lastBrent = brent.price;
  } catch (error) {
    console.error('Bot error:', error.message);
  }
});

console.log('Trading bot started. Checking spread every 5 minutes...');

Production Best Practices

1. Environment Variables

Never hardcode API keys. Use environment variables with dotenv:

require('dotenv').config();

const client = new OilPriceAPIClient({
  apiKey: process.env.OIL_PRICE_API_KEY
});

2. Implement Caching

Reduce API calls by caching responses for 1-5 minutes:

const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 300 }); // 5 minute TTL

async function getCachedPrice(code) {
  const cached = cache.get(code);
  if (cached) return cached;

  const price = await client.getLatestPrice({ code });
  cache.set(code, price);
  return price;
}

3. Graceful Error Handling

Always handle errors and provide fallbacks:

async function safeGetPrice(code) {
  try {
    return await client.getLatestPrice({ code });
  } catch (error) {
    console.error(`Failed to fetch ${code}: ${error.message}`);

    // Return cached or default value
    return cache.get(code) || { price: null, error: true };
  }
}

4. Rate Limiting

Respect API rate limits with a queue:

const PQueue = require('p-queue').default;
const queue = new PQueue({ concurrency: 5, interval: 1000 });

async function queuedRequest(code) {
  return queue.add(() => client.getLatestPrice({ code }));
}

5. Logging

Use structured logging for production:

const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

async function loggedRequest(code) {
  logger.info('Fetching price', { commodity: code });

  try {
    const price = await client.getLatestPrice({ code });
    logger.info('Price fetched successfully', { code, price: price.price });
    return price;
  } catch (error) {
    logger.error('Failed to fetch price', { code, error: error.message });
    throw error;
  }
}

Frequently Asked Questions

Q: How do I get oil prices in Node.js?

A: Install the @oilpriceapi/client package with npm install @oilpriceapi/client, sign up for a free API key at oilpriceapi.com, then use client.getLatestPrice({ code: "WTI_USD" }) to fetch current prices.

Q: Is there a free Node.js oil price API?

A: Yes. OilPriceAPI offers 100 free API requests with every account (no credit card required). The official Node.js SDK supports both async/await and promises for modern JavaScript development.

Q: Does the Node.js SDK support TypeScript?

A: Yes. The @oilpriceapi/client package includes full TypeScript definitions with type safety, autocomplete, and inline documentation in your IDE.

Q: How do I build a Node.js trading bot for oil?

A: Use the OilPriceAPI Node.js SDK to fetch real-time prices with setInterval or cron jobs, implement your trading logic (e.g., spread analysis), and execute trades via your broker's API. WebSocket support enables low-latency price streams for high-frequency strategies.

Start Building with Node.js Today

You now have everything you need to fetch and process oil prices in Node.js. Whether you're building an Express API, Next.js application, Discord bot, or trading system, the OilPriceAPI SDK makes it simple and reliable.

Ready to Get Started?

Install the SDK and get your free API key. 100 API requests included, no credit card required.

npm install @oilpriceapi/client

100 free API requests • 100+ commodities • Real-time prices • Full TypeScript support