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

Natural Gas (UK)

UK natural gas pricing in British pence per therm.

API Field: NATURAL_GAS_GBP
Unit: pence/therm
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

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.