Skip to main content
C++ Integration

C++ Oil Price API

Integrate real-time oil and commodity prices into your C++ applications. High-performance with modern C++17 features, async processing, and cross-platform support.

Quick Start

1. Install Dependencies

# Ubuntu/Debian
sudo apt-get install libcurl4-openssl-dev nlohmann-json3-dev
# macOS with Homebrew
brew install curl nlohmann-json
# Build with CMake
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

2. C++ Features

  • Modern C++17 with RAII and smart pointers
  • Async processing with std::future
  • Cross-platform (Windows, Linux, macOS)

Basic Integration with libcurl

#include <iostream>
#include <string>
#include <map>
#include <memory>
#include <curl/curl.h>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

class OilPriceAPI {
private:
    std::string api_key_;
    std::string base_url_;
    
    // Callback function for libcurl to write data
    static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) {
        userp->append((char*)contents, size * nmemb);
        return size * nmemb;
    }
    
    // Make HTTP GET request
    std::pair<long, std::string> makeRequest(const std::string& endpoint) {
        CURL* curl;
        CURLcode res;
        std::string response_body;
        long response_code = 0;
        
        curl = curl_easy_init();
        if (!curl) {
            throw std::runtime_error("Failed to initialize libcurl");
        }
        
        std::string url = base_url_ + endpoint;
        struct curl_slist* headers = nullptr;
        
        // Set headers
        std::string auth_header = "Authorization: Token " + api_key_;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        headers = curl_slist_append(headers, auth_header.c_str());
        
        // Configure curl
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_body);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
        curl_easy_setopt(curl, CURLOPT_USERAGENT, "OilPriceAPI-CPP-Client/1.0");
        
        // Perform request
        res = curl_easy_perform(curl);
        
        if (res == CURLE_OK) {
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
        }
        
        // Cleanup
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
        
        if (res != CURLE_OK) {
            throw std::runtime_error("HTTP request failed: " + std::string(curl_easy_strerror(res)));
        }
        
        return std::make_pair(response_code, response_body);
    }
    
public:
    OilPriceAPI(const std::string& api_key) 
        : api_key_(api_key), base_url_("https://api.oilpriceapi.com") {
        // Initialize libcurl globally (call once per application)
        curl_global_init(CURL_GLOBAL_DEFAULT);
    }
    
    ~OilPriceAPI() {
        // Cleanup libcurl globally
        curl_global_cleanup();
    }
    
    json getBrentPrice() {
        auto [status_code, response_body] = makeRequest("/prices");
        
        if (status_code != 200) {
            throw std::runtime_error("HTTP Error: " + std::to_string(status_code));
        }
        
        return json::parse(response_body);
    }
    
    json getCommodityHealth() {
        auto [status_code, response_body] = makeRequest("/health");
        
        if (status_code != 200) {
            throw std::runtime_error("HTTP Error: " + std::to_string(status_code));
        }
        
        return json::parse(response_body);
    }
    
    struct CommodityPrice {
        double price;
        std::string timestamp;
        std::string currency;
        std::string unit;
        
        CommodityPrice(double p, const std::string& ts, const std::string& curr, const std::string& u)
            : price(p), timestamp(ts), currency(curr), unit(u) {}
    };
    
    std::optional<CommodityPrice> getWTIPrice() {
        try {
            json health_data = getCommodityHealth();
            
            if (!health_data.contains("metrics") || 
                !health_data["metrics"].contains("commodity_health") ||
                !health_data["metrics"]["commodity_health"].contains("WTI_USD")) {
                return std::nullopt;
            }
            
            auto wti_data = health_data["metrics"]["commodity_health"]["WTI_USD"];
            
            if (!wti_data.contains("latest_price") || !wti_data.contains("last_update")) {
                return std::nullopt;
            }
            
            double latest_price = wti_data["latest_price"].get<double>();
            std::string last_update = wti_data["last_update"].get<std::string>();
            
            return CommodityPrice(
                latest_price / 100.0,  // Convert from cents
                last_update,
                "USD",
                "barrel"
            );
            
        } catch (const std::exception& e) {
            std::cerr << "Error getting WTI price: " << e.what() << std::endl;
            return std::nullopt;
        }
    }
    
    std::map<std::string, CommodityPrice> getAllCommodities() {
        std::map<std::string, CommodityPrice> commodities;
        
        try {
            // Get Brent from prices endpoint
            json brent_response = getBrentPrice();
            if (brent_response.contains("data")) {
                auto data = brent_response["data"];
                commodities.emplace("brent_crude", CommodityPrice(
                    data["price"].get<double>(),
                    data["timestamp"].get<std::string>(),
                    data["currency"].get<std::string>(),
                    "barrel"
                ));
            }
            
            // Get other commodities from health endpoint
            json health_response = getCommodityHealth();
            if (health_response.contains("metrics") && 
                health_response["metrics"].contains("commodity_health")) {
                
                auto commodity_health = health_response["metrics"]["commodity_health"];
                
                for (auto& [key, data] : commodity_health.items()) {
                    if (data.contains("latest_price") && data.contains("last_update")) {
                        double scale = isCurrencyPair(key) ? 10000.0 : 100.0;
                        double price = data["latest_price"].get<double>() / scale;
                        
                        std::string lowercase_key = key;
                        std::transform(lowercase_key.begin(), lowercase_key.end(), lowercase_key.begin(), ::tolower);
                        
                        commodities.emplace(lowercase_key, CommodityPrice(
                            price,
                            data["last_update"].get<std::string>(),
                            "USD",
                            getUnit(key)
                        ));
                    }
                }
            }
            
        } catch (const std::exception& e) {
            std::cerr << "Error getting commodities: " << e.what() << std::endl;
        }
        
        return commodities;
    }
    
private:
    bool isCurrencyPair(const std::string& commodity_key) {
        return commodity_key == "EUR_USD" || commodity_key == "GBP_USD";
    }
    
    std::string getUnit(const std::string& commodity_key) {
        static const std::map<std::string, std::string> units = {
            {"WTI_USD", "barrel"},
            {"NATURAL_GAS_USD", "MMBtu"},
            {"GOLD_USD", "ounce"},
            {"EUR_USD", "USD"},
            {"GBP_USD", "USD"}
        };
        
        auto it = units.find(commodity_key);
        return (it != units.end()) ? it->second : "unit";
    }
};

// Usage example
int main() {
    try {
        OilPriceAPI api("YOUR_API_KEY_HERE");
        
        std::cout << "=== Live Oil Prices ===" << std::endl;
        
        // Get Brent crude price
        json brent_data = api.getBrentPrice();
        if (brent_data.contains("data")) {
            auto data = brent_data["data"];
            std::cout << "Brent Crude: $" << data["price"].get<double>() << "/barrel" << std::endl;
        }
        
        // Get WTI price
        auto wti_price = api.getWTIPrice();
        if (wti_price) {
            std::cout << "WTI Crude: $" << std::fixed << std::setprecision(2) 
                      << wti_price->price << "/" << wti_price->unit << std::endl;
        }
        
        // Get all commodities
        auto all_commodities = api.getAllCommodities();
        for (const auto& [name, price] : all_commodities) {
            std::cout << name << ": $" << std::fixed << std::setprecision(2) 
                      << price.price << "/" << price.unit << std::endl;
        }
        
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    
    return 0;
}

Modern C++17 with Async Processing

Enhanced version using modern C++ features, RAII, and async processing:

#include <iostream>
#include <string>
#include <map>
#include <future>
#include <memory>
#include <chrono>
#include <iomanip>
#include <sstream>
#include <curl/curl.h>
#include <nlohmann/json.hpp>

using json = nlohmann::json;
using namespace std::chrono_literals;

class ModernOilPriceAPI {
public:
    struct PriceData {
        double price;
        std::chrono::system_clock::time_point timestamp;
        std::string currency;
        std::string unit;
        
        PriceData(double p, const std::string& ts, const std::string& curr, const std::string& u)
            : price(p), currency(curr), unit(u) {
            // Parse ISO 8601 timestamp
            std::istringstream ss(ts);
            std::tm tm = {};
            ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S");
            timestamp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
        }
        
        std::string getFormattedTimestamp() const {
            auto time_t = std::chrono::system_clock::to_time_t(timestamp);
            std::stringstream ss;
            ss << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S");
            return ss.str();
        }
    };
    
    enum class CommodityType {
        BRENT_CRUDE,
        WTI_CRUDE,
        NATURAL_GAS,
        GOLD,
        EUR_USD,
        GBP_USD
    };

private:
    std::string api_key_;
    std::string base_url_;
    std::unique_ptr<CURL, decltype(&curl_easy_cleanup)> curl_;
    
    static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) {
        userp->append(static_cast<char*>(contents), size * nmemb);
        return size * nmemb;
    }
    
    std::future<json> makeAsyncRequest(const std::string& endpoint) {
        return std::async(std::launch::async, [this, endpoint]() -> json {
            return makeRequest(endpoint);
        });
    }
    
    json makeRequest(const std::string& endpoint) {
        if (!curl_) {
            throw std::runtime_error("CURL not initialized");
        }
        
        std::string response_body;
        std::string url = base_url_ + endpoint;
        
        struct curl_slist* headers = nullptr;
        std::string auth_header = "Authorization: Token " + api_key_;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        headers = curl_slist_append(headers, auth_header.c_str());
        
        // Configure CURL
        curl_easy_setopt(curl_.get(), CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl_.get(), CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl_.get(), CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl_.get(), CURLOPT_WRITEDATA, &response_body);
        curl_easy_setopt(curl_.get(), CURLOPT_TIMEOUT, 10L);
        curl_easy_setopt(curl_.get(), CURLOPT_CONNECTTIMEOUT, 5L);
        curl_easy_setopt(curl_.get(), CURLOPT_SSL_VERIFYPEER, 1L);
        curl_easy_setopt(curl_.get(), CURLOPT_SSL_VERIFYHOST, 2L);
        
        CURLcode res = curl_easy_perform(curl_.get());
        curl_slist_free_all(headers);
        
        if (res != CURLE_OK) {
            throw std::runtime_error("HTTP request failed: " + std::string(curl_easy_strerror(res)));
        }
        
        long response_code;
        curl_easy_getinfo(curl_.get(), CURLINFO_RESPONSE_CODE, &response_code);
        
        if (response_code != 200) {
            throw std::runtime_error("HTTP Error: " + std::to_string(response_code));
        }
        
        return json::parse(response_body);
    }

public:
    explicit ModernOilPriceAPI(const std::string& api_key) 
        : api_key_(api_key), 
          base_url_("https://api.oilpriceapi.com"),
          curl_(curl_easy_init(), curl_easy_cleanup) {
        
        if (!curl_) {
            throw std::runtime_error("Failed to initialize libcurl");
        }
        
        // Initialize libcurl globally (should be called once)
        curl_global_init(CURL_GLOBAL_DEFAULT);
    }
    
    ~ModernOilPriceAPI() {
        curl_global_cleanup();
    }
    
    // Async methods using std::future
    std::future<std::optional<PriceData>> getBrentPriceAsync() {
        return std::async(std::launch::async, [this]() -> std::optional<PriceData> {
            try {
                json response = makeRequest("/prices");
                if (response.contains("data")) {
                    auto data = response["data"];
                    return PriceData(
                        data["price"].get<double>(),
                        data["timestamp"].get<std::string>(),
                        data["currency"].get<std::string>(),
                        "barrel"
                    );
                }
                return std::nullopt;
            } catch (const std::exception& e) {
                std::cerr << "Error getting Brent price: " << e.what() << std::endl;
                return std::nullopt;
            }
        });
    }
    
    std::future<std::optional<PriceData>> getWTIPriceAsync() {
        return std::async(std::launch::async, [this]() -> std::optional<PriceData> {
            try {
                json health_data = makeRequest("/health");
                auto wti_data = health_data["metrics"]["commodity_health"]["WTI_USD"];
                
                if (wti_data.contains("latest_price") && wti_data.contains("last_update")) {
                    return PriceData(
                        wti_data["latest_price"].get<double>() / 100.0,
                        wti_data["last_update"].get<std::string>(),
                        "USD",
                        "barrel"
                    );
                }
                return std::nullopt;
            } catch (const std::exception& e) {
                std::cerr << "Error getting WTI price: " << e.what() << std::endl;
                return std::nullopt;
            }
        });
    }
    
    std::future<std::map<std::string, PriceData>> getAllCommoditiesAsync() {
        return std::async(std::launch::async, [this]() -> std::map<std::string, PriceData> {
            std::map<std::string, PriceData> commodities;
            
            try {
                // Launch both requests concurrently
                auto brent_future = makeAsyncRequest("/prices");
                auto health_future = makeAsyncRequest("/health");
                
                // Get Brent data
                try {
                    json brent_response = brent_future.get();
                    if (brent_response.contains("data")) {
                        auto data = brent_response["data"];
                        commodities.emplace("brent_crude", PriceData(
                            data["price"].get<double>(),
                            data["timestamp"].get<std::string>(),
                            data["currency"].get<std::string>(),
                            "barrel"
                        ));
                    }
                } catch (const std::exception& e) {
                    std::cerr << "Error processing Brent data: " << e.what() << std::endl;
                }
                
                // Get health data
                try {
                    json health_response = health_future.get();
                    if (health_response.contains("metrics") && 
                        health_response["metrics"].contains("commodity_health")) {
                        
                        auto commodity_health = health_response["metrics"]["commodity_health"];
                        
                        for (auto& [key, data] : commodity_health.items()) {
                            if (data.contains("latest_price") && data.contains("last_update")) {
                                double scale = isCurrencyPair(key) ? 10000.0 : 100.0;
                                double price = data["latest_price"].get<double>() / scale;
                                
                                std::string lowercase_key = key;
                                std::transform(lowercase_key.begin(), lowercase_key.end(), 
                                             lowercase_key.begin(), ::tolower);
                                
                                commodities.emplace(lowercase_key, PriceData(
                                    price,
                                    data["last_update"].get<std::string>(),
                                    "USD",
                                    getUnit(key)
                                ));
                            }
                        }
                    }
                } catch (const std::exception& e) {
                    std::cerr << "Error processing health data: " << e.what() << std::endl;
                }
                
            } catch (const std::exception& e) {
                std::cerr << "Error in getAllCommoditiesAsync: " << e.what() << std::endl;
            }
            
            return commodities;
        });
    }
    
    // Synchronous convenience methods
    std::optional<PriceData> getBrentPrice() {
        return getBrentPriceAsync().get();
    }
    
    std::optional<PriceData> getWTIPrice() {
        return getWTIPriceAsync().get();
    }
    
    std::map<std::string, PriceData> getAllCommodities() {
        return getAllCommoditiesAsync().get();
    }

private:
    bool isCurrencyPair(const std::string& commodity_key) const {
        return commodity_key == "EUR_USD" || commodity_key == "GBP_USD";
    }
    
    std::string getUnit(const std::string& commodity_key) const {
        static const std::unordered_map<std::string, std::string> units = {
            {"WTI_USD", "barrel"},
            {"NATURAL_GAS_USD", "MMBtu"},
            {"GOLD_USD", "ounce"},
            {"EUR_USD", "USD"},
            {"GBP_USD", "USD"}
        };
        
        auto it = units.find(commodity_key);
        return (it != units.end()) ? it->second : "unit";
    }
};

// Modern usage example with async processing
int main() {
    try {
        ModernOilPriceAPI api("YOUR_API_KEY_HERE");
        
        std::cout << "=== Fetching Live Prices Asynchronously ===" << std::endl;
        
        // Launch all requests asynchronously
        auto brent_future = api.getBrentPriceAsync();
        auto wti_future = api.getWTIPriceAsync();
        auto all_future = api.getAllCommoditiesAsync();
        
        // Wait for and process results
        auto brent_price = brent_future.get();
        if (brent_price) {
            std::cout << "Brent Crude: $" << std::fixed << std::setprecision(2) 
                      << brent_price->price << "/" << brent_price->unit 
                      << " (updated: " << brent_price->getFormattedTimestamp() << ")" << std::endl;
        }
        
        auto wti_price = wti_future.get();
        if (wti_price) {
            std::cout << "WTI Crude: $" << std::fixed << std::setprecision(2) 
                      << wti_price->price << "/" << wti_price->unit 
                      << " (updated: " << wti_price->getFormattedTimestamp() << ")" << std::endl;
        }
        
        std::cout << "\n=== All Commodities ===" << std::endl;
        auto all_commodities = all_future.get();
        for (const auto& [name, price] : all_commodities) {
            std::cout << name << ": $" << std::fixed << std::setprecision(4) 
                      << price.price << "/" << price.unit << std::endl;
        }
        
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    
    return 0;
}

Using Microsoft cpprestsdk

Alternative implementation using Microsoft's cpprestsdk for modern async HTTP:

// Using Microsoft's cpprestsdk for modern C++ HTTP client
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <cpprest/json.h>
#include <iostream>
#include <memory>
#include <string>
#include <map>

using namespace web;
using namespace web::http;
using namespace web::http::client;

class CppRestOilPriceAPI {
private:
    std::string api_key_;
    std::unique_ptr<http_client> client_;
    
public:
    explicit CppRestOilPriceAPI(const std::string& api_key) 
        : api_key_(api_key) {
        
        http_client_config config;
        config.set_timeout(std::chrono::seconds(10));
        
        client_ = std::make_unique<http_client>(
            U("https://api.oilpriceapi.com"), 
            config
        );
    }
    
    pplx::task<json::value> getBrentPriceAsync() {
        http_request request(methods::GET);
        request.headers().add(U("Authorization"), U("Token " + api_key_));
        request.headers().add(U("Content-Type"), U("application/json"));
        
        return client_->request(request, U("/prices"))
            .then([](http_response response) -> pplx::task<json::value> {
                if (response.status_code() == status_codes::OK) {
                    return response.extract_json();
                }
                throw std::runtime_error("HTTP Error: " + std::to_string(response.status_code()));
            });
    }
    
    pplx::task<json::value> getCommodityHealthAsync() {
        http_request request(methods::GET);
        request.headers().add(U("Authorization"), U("Token " + api_key_));
        request.headers().add(U("Content-Type"), U("application/json"));
        
        return client_->request(request, U("/health"))
            .then([](http_response response) -> pplx::task<json::value> {
                if (response.status_code() == status_codes::OK) {
                    return response.extract_json();
                }
                throw std::runtime_error("HTTP Error: " + std::to_string(response.status_code()));
            });
    }
    
    pplx::task<std::map<std::string, double>> getAllPricesAsync() {
        // Launch both requests concurrently
        auto brent_task = getBrentPriceAsync();
        auto health_task = getCommodityHealthAsync();
        
        return pplx::when_all(brent_task, health_task)
            .then([](std::vector<json::value> results) -> std::map<std::string, double> {
                std::map<std::string, double> prices;
                
                try {
                    // Process Brent data (results[0])
                    if (results[0].has_field(U("data"))) {
                        auto data = results[0][U("data")];
                        if (data.has_field(U("price"))) {
                            prices["brent_crude"] = data[U("price")].as_double();
                        }
                    }
                    
                    // Process health data (results[1])
                    if (results[1].has_field(U("metrics"))) {
                        auto metrics = results[1][U("metrics")];
                        if (metrics.has_field(U("commodity_health"))) {
                            auto commodity_health = metrics[U("commodity_health")];
                            
                            for (auto& pair : commodity_health.as_object()) {
                                auto key = utility::conversions::to_utf8string(pair.first);
                                auto data = pair.second;
                                
                                if (data.has_field(U("latest_price"))) {
                                    double scale = (key == "EUR_USD" || key == "GBP_USD") ? 10000.0 : 100.0;
                                    double price = data[U("latest_price")].as_double() / scale;
                                    
                                    std::transform(key.begin(), key.end(), key.begin(), ::tolower);
                                    prices[key] = price;
                                }
                            }
                        }
                    }
                } catch (const std::exception& e) {
                    std::cerr << "Error processing price data: " << e.what() << std::endl;
                }
                
                return prices;
            });
    }
};

// Usage example with cpprestsdk
void demonstrateCppRest() {
    try {
        CppRestOilPriceAPI api("YOUR_API_KEY_HERE");
        
        std::cout << "=== Using cpprestsdk for async HTTP ===" << std::endl;
        
        // Get all prices asynchronously
        api.getAllPricesAsync()
            .then([](std::map<std::string, double> prices) {
                std::cout << "\n=== Live Commodity Prices ===" << std::endl;
                
                for (const auto& [name, price] : prices) {
                    std::cout << name << ": $" << std::fixed << std::setprecision(2) 
                              << price << std::endl;
                }
            })
            .then([](pplx::task<void> previous_task) {
                try {
                    previous_task.wait();
                } catch (const std::exception& e) {
                    std::cerr << "Error: " << e.what() << std::endl;
                }
            })
            .wait();
            
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
}

CMake Build Configuration

Complete CMakeLists.txt for building your Oil Price API client:

# CMakeLists.txt for Oil Price API C++ client

cmake_minimum_required(VERSION 3.15)
project(OilPriceAPI VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Find required packages
find_package(PkgConfig REQUIRED)
find_package(nlohmann_json 3.11.0 REQUIRED)

# Find libcurl
pkg_check_modules(CURL REQUIRED libcurl)

# Optional: Find cpprestsdk
find_package(cpprestsdk QUIET)

# Create library for Oil Price API client
add_library(oilpriceapi STATIC
    src/oil_price_api.cpp
    src/oil_price_api.h
)

target_link_libraries(oilpriceapi
    PRIVATE
        nlohmann_json::nlohmann_json
        ${CURL_LIBRARIES}
)

target_include_directories(oilpriceapi
    PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/include
    PRIVATE
        ${CURL_INCLUDE_DIRS}
)

target_compile_options(oilpriceapi
    PRIVATE
        ${CURL_CFLAGS_OTHER}
)

# Create executable examples
add_executable(basic_example examples/basic_example.cpp)
target_link_libraries(basic_example oilpriceapi)

add_executable(modern_example examples/modern_example.cpp)
target_link_libraries(modern_example oilpriceapi)

# Optional: cpprestsdk example
if(cpprestsdk_FOUND)
    add_executable(cpprest_example examples/cpprest_example.cpp)
    target_link_libraries(cpprest_example 
        cpprestsdk::cpprest
        nlohmann_json::nlohmann_json
    )
endif()

# Installation
install(TARGETS oilpriceapi
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION bin
)

install(DIRECTORY include/ DESTINATION include)

# Package configuration
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
    "${CMAKE_CURRENT_BINARY_DIR}/OilPriceAPIConfigVersion.cmake"
    VERSION ${PROJECT_VERSION}
    COMPATIBILITY AnyNewerVersion
)

export(TARGETS oilpriceapi
    FILE "${CMAKE_CURRENT_BINARY_DIR}/OilPriceAPITargets.cmake"
)

# Build instructions:
# mkdir build && cd build
# cmake .. -DCMAKE_BUILD_TYPE=Release
# make -j$(nproc)

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

WAHA Natural Gas

WAHA Hub natural gas spot price from the Permian Basin. Regional pricing benchmark reflecting Midland-area production and pipeline capacity constraints. Can trade at negative prices during pipeline congestion.

API Field: NATURAL_GAS_WAHA
Unit: MMBtu
Endpoint: /prices

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

Propane

Mont Belvieu propane spot price — the key U.S. NGL benchmark for residential heating, petrochemical feedstock, and agricultural drying.

API Field: PROPANE_MONT_BELVIEU_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

Newcastle Coal (API6)

Newcastle Coal (API6) — the Asian thermal coal benchmark price per metric ton, widely used for pricing coal imports in Asia-Pacific.

API Field: NEWCASTLE_COAL_USD
Unit: MT
Endpoint: /health

Coking Coal

Metallurgical (coking) coal price per metric ton, essential feedstock for steelmaking in blast furnaces.

API Field: COKING_COAL_USD
Unit: MT
Endpoint: /health

Central Appalachian Coal

Central Appalachian (CAPP) thermal coal spot price, a key US East Coast coal benchmark from EIA weekly data.

API Field: CAPP_COAL_USD
Unit: short_ton
Endpoint: /health

Powder River Basin Coal

Powder River Basin (Wyoming) thermal coal spot price, the lowest-cost US coal basin. EIA weekly data.

API Field: PRB_COAL_USD
Unit: short_ton
Endpoint: /health

Illinois Basin Coal

Illinois Basin thermal coal spot price, a major US interior coal benchmark. EIA weekly data.

API Field: ILLINOIS_COAL_USD
Unit: short_ton
Endpoint: /health

US Natural Gas Storage

US weekly natural gas storage inventory levels in billion cubic feet (Bcf), a key supply indicator from EIA.

API Field: NATURAL_GAS_STORAGE
Unit: Bcf
Endpoint: /health

Gold

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

API Field: GOLD_USD
Unit: ounce
Endpoint: /health

Silver

Silver spot price, a precious metal used in jewelry, electronics, solar panels, and as an investment asset.

API Field: SILVER_USD
Unit: ounce
Endpoint: /health

Platinum

Platinum spot price, a precious metal critical for automotive catalytic converters, jewelry, and industrial applications.

API Field: PLATINUM_USD
Unit: ounce
Endpoint: /health

Palladium

Palladium spot price, a precious metal essential for gasoline vehicle catalytic converters and electronics.

API Field: PALLADIUM_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

USD/CNY

US Dollar to Chinese Yuan exchange rate, critical for global commodity trade and Asian energy markets.

API Field: USD_CNY
Unit: CNY
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

Azeri Light Crude Oil

Azeri Light (BTC) Crude Oil — key Caspian/Mediterranean benchmark transported via Baku-Tbilisi-Ceyhan pipeline, important for European refiners.

API Field: AZERI_LIGHT_USD
Unit: barrel
Endpoint: /prices

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

OPEC Basket

OPEC Reference Basket — a weighted average of petroleum blends from OPEC member countries, used as a benchmark for OPEC production decisions.

API Field: OPEC_BASKET_USD
Unit: barrel
Endpoint: /health

Basrah Medium Crude

Iraqi Basrah Medium crude oil — a key Middle Eastern export grade and benchmark for Asian and European refiners.

API Field: BASRAH_MEDIUM_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

ICE Gasoil (Rotterdam)

ICE Low Sulphur Gasoil futures — the European diesel benchmark delivered in Amsterdam-Rotterdam-Antwerp (ARA). Used for pricing diesel, heating oil, and jet fuel across Europe.

API Field: GASOIL_USD
Unit: tonne
Endpoint: /health

Jet A-1 (Northwest Europe)

Jet A-1 aviation fuel spot price for Northwest Europe (NWE basis). The primary benchmark for European airline fuel procurement and aviation fuel hedging.

API Field: JET_A1_NWE_USD
Unit: barrel
Endpoint: /health

Singapore Jet Kerosene

Singapore Platts Jet Kerosene (Jet A-1) spot price — the Asia-Pacific aviation fuel benchmark used by airlines across Asia, Australia, and the Middle East.

API Field: SINGAPORE_JET_KEROSENE_USD
Unit: barrel
Endpoint: /health

Singapore Mogas 92

Singapore Platts Mogas 92 RON gasoline benchmark — the primary Asia-Pacific gasoline reference price used for gasoline trading and pricing across Asia.

API Field: SINGAPORE_MOGAS_92_USD
Unit: MT
Endpoint: /health

Jet Fuel (A4A/Argus Index)

Airlines for America (A4A) Jet Fuel Cost Index based on Argus spot prices from Chicago, Houston, Los Angeles, and New York. The U.S. airline industry standard for fuel cost benchmarking.

API Field: JET_FUEL_A4A_USD
Unit: gallon
Endpoint: /health

Asphalt

Asphalt (bitumen) spot price per metric ton, a refined petroleum product used in road construction and roofing.

API Field: ASPHALT_USD
Unit: metric_ton
Endpoint: /health

Naphtha

Naphtha spot price per metric ton, a light petroleum distillate used as a petrochemical feedstock and gasoline blending component.

API Field: NAPHTHA_USD
Unit: metric_ton
Endpoint: /health

Methanol

Methanol (methyl alcohol) spot price per metric ton, a key chemical feedstock used in plastics, fuels, and industrial applications.

API Field: METHANOL_USD
Unit: metric_ton
Endpoint: /health

Ethylene

Ethylene spot price per metric ton, the world's most-produced organic compound and foundational petrochemical feedstock for plastics.

API Field: ETHYLENE_USD
Unit: metric_ton
Endpoint: /health

Polyethylene

Polyethylene spot price per metric ton, the world's most widely used plastic polymer derived from ethylene.

API Field: POLYETHYLENE_USD
Unit: metric_ton
Endpoint: /health

Polypropylene

Polypropylene spot price per metric ton, a versatile thermoplastic polymer used in packaging, automotive parts, and textiles.

API Field: POLYPROPYLENE_USD
Unit: metric_ton
Endpoint: /health

Urea

Urea (fertilizer-grade) spot price per metric ton, a nitrogen-based fertilizer and industrial chemical derived from natural gas.

API Field: UREA_USD
Unit: metric_ton
Endpoint: /health

Ammonia

Ammonia spot price per metric ton, a key nitrogen feedstock for fertilizers and a growing green hydrogen carrier.

API Field: AMMONIA_USD
Unit: metric_ton
Endpoint: /health

Biodiesel

Biodiesel spot price per gallon, a renewable fuel produced from vegetable oils and animal fats, used as a diesel substitute or blending component.

API Field: BIODIESEL_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: /prices

UK Carbon Allowances

UK Emissions Trading Scheme (UK ETS) carbon allowance pricing. Post-Brexit separate market from EU ETS.

API Field: UK_CARBON_GBP
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

C++ Best Practices

Memory Management

  • Use RAII and smart pointers
  • Proper cleanup of libcurl resources
  • Exception safety with RAII

Performance

  • Use async processing for concurrent requests
  • Reuse CURL handles for multiple requests
  • Implement connection pooling

Ready to Start Building?

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