Oil Price API Documentation - Quick Start in 5 Minutes | REST API
GitHub
GitHub

R Language Integration Guide

Integrate OilPriceAPI into your R scripts and applications for real-time crude oil prices, Brent crude data, natural gas rates, and commodity market analysis for energy research and financial modeling.

Requirements

  • R 4.0 or higher
  • httr or httr2 package
  • jsonlite package

Installation

# Install required packages
install.packages(c("httr", "jsonlite"))

# Optional: for data manipulation and visualization
install.packages(c("dplyr", "ggplot2", "lubridate"))

# Alternative: httr2 (modern HTTP client)
install.packages("httr2")

Quick Start

Using httr

library(httr)
library(jsonlite)

api_key <- Sys.getenv("OILPRICE_API_KEY")

response <- GET(
  "https://api.oilpriceapi.com/v1/prices/latest",
  query = list(by_code = "WTI_USD"),
  add_headers(Authorization = paste("Token", api_key))
)

data <- content(response, as = "parsed")
cat("WTI Price:", data$data$WTI_USD$formatted, "\n")

Using httr2

library(httr2)

api_key <- Sys.getenv("OILPRICE_API_KEY")

response <- request("https://api.oilpriceapi.com/v1/prices/latest") |>
  req_url_query(by_code = "WTI_USD") |>
  req_headers(Authorization = paste("Token", api_key)) |>
  req_perform()

data <- resp_body_json(response)
cat("WTI Price:", data$data$WTI_USD$formatted, "\n")

Complete API Client Functions

library(httr)
library(jsonlite)

# Configuration
OILPRICE_BASE_URL <- "https://api.oilpriceapi.com/v1"

#' Create OilPriceAPI client configuration
#'
#' @param api_key API key (defaults to OILPRICE_API_KEY env var)
#' @return List with API configuration
create_client <- function(api_key = NULL) {
  if (is.null(api_key)) {
    api_key <- Sys.getenv("OILPRICE_API_KEY")
  }

  if (api_key == "") {
    stop("API key is required. Set OILPRICE_API_KEY environment variable.")
  }

  list(
    api_key = api_key,
    base_url = OILPRICE_BASE_URL
  )
}

#' Make authenticated API request
#'
#' @param client Client configuration
#' @param endpoint API endpoint
#' @param params Query parameters
#' @return Parsed response data
api_request <- function(client, endpoint, params = list()) {
  url <- paste0(client$base_url, endpoint)

  response <- GET(
    url,
    query = params,
    add_headers(
      Authorization = paste("Token", client$api_key),
      `Content-Type` = "application/json"
    ),
    timeout(30)
  )

  status <- status_code(response)

  if (status == 401) {
    stop("Authentication failed: Invalid API key")
  } else if (status == 429) {
    stop("Rate limit exceeded. Please wait before making more requests.")
  } else if (status >= 400) {
    stop(paste("API error: HTTP", status))
  }

  content(response, as = "parsed")
}

#' Get latest commodity prices
#'
#' @param client Client configuration
#' @param codes Character vector of commodity codes
#' @return Data frame with price information
get_latest_prices <- function(client, codes) {
  if (is.vector(codes) && length(codes) > 1) {
    codes <- paste(codes, collapse = ",")
  }

  response <- api_request(client, "/prices/latest", list(by_code = codes))

  # Convert to data frame
  prices_list <- lapply(names(response$data), function(code) {
    item <- response$data[[code]]
    data.frame(
      code = code,
      price = item$price,
      formatted = item$formatted,
      currency = item$currency,
      created_at = item$created_at,
      stringsAsFactors = FALSE
    )
  })

  do.call(rbind, prices_list)
}

#' Get historical prices
#'
#' @param client Client configuration
#' @param code Commodity code
#' @param days Number of days (7, 30, 90, 365)
#' @return Data frame with historical prices
get_historical_prices <- function(client, code, days = 7) {
  endpoint <- paste0("/prices/past_", days, "_days")
  response <- api_request(client, endpoint, list(by_code = code))

  # Convert to data frame
  df <- do.call(rbind, lapply(response$data, function(item) {
    data.frame(
      price = item$price,
      formatted = item$formatted,
      created_at = item$created_at,
      stringsAsFactors = FALSE
    )
  }))

  df$code <- code
  df$created_at <- as.POSIXct(df$created_at, format = "%Y-%m-%dT%H:%M:%S")
  df
}

#' Get available commodities
#'
#' @param client Client configuration
#' @return Data frame with commodity information
get_commodities <- function(client) {
  response <- api_request(client, "/commodities")

  do.call(rbind, lapply(response$data, function(item) {
    data.frame(
      code = item$code,
      name = item$name,
      category = item$category,
      stringsAsFactors = FALSE
    )
  }))
}

Usage Examples

Fetch Multiple Commodities

library(dplyr)

# Create client
client <- create_client()

# Get multiple oil prices
commodities <- c("WTI_USD", "BRENT_CRUDE_USD", "NATURAL_GAS_USD")
prices <- get_latest_prices(client, commodities)

# Display results
print(prices)

# Format output
prices %>%
  select(code, formatted) %>%
  print()

Historical Price Analysis

library(dplyr)
library(ggplot2)

client <- create_client()

# Get past month of WTI prices
history <- get_historical_prices(client, "WTI_USD", days = 30)

# Summary statistics
summary_stats <- history %>%
  summarise(
    mean_price = mean(price),
    min_price = min(price),
    max_price = max(price),
    sd_price = sd(price),
    n_observations = n()
  )

print(summary_stats)

# Plot price history
ggplot(history, aes(x = created_at, y = price)) +
  geom_line(color = "steelblue", linewidth = 1) +
  geom_smooth(method = "loess", se = TRUE, alpha = 0.2) +
  labs(
    title = "WTI Crude Oil Price - Past 30 Days",
    x = "Date",
    y = "Price (USD)"
  ) +
  theme_minimal()

Price Comparison Analysis

library(dplyr)
library(tidyr)
library(ggplot2)

client <- create_client()

# Fetch historical data for multiple commodities
commodities <- c("WTI_USD", "BRENT_CRUDE_USD")

all_history <- lapply(commodities, function(code) {
  df <- get_historical_prices(client, code, days = 30)
  df$commodity <- code
  df
}) %>%
  bind_rows()

# Calculate spread between Brent and WTI
spread_analysis <- all_history %>%
  select(created_at, commodity, price) %>%
  pivot_wider(names_from = commodity, values_from = price) %>%
  mutate(spread = BRENT_CRUDE_USD - WTI_USD) %>%
  filter(!is.na(spread))

# Plot spread over time
ggplot(spread_analysis, aes(x = created_at, y = spread)) +
  geom_line(color = "darkgreen", linewidth = 1) +
  geom_hline(yintercept = mean(spread_analysis$spread, na.rm = TRUE),
             linetype = "dashed", color = "red") +
  labs(
    title = "Brent-WTI Spread Analysis",
    x = "Date",
    y = "Spread (USD)"
  ) +
  theme_minimal()

Shiny Dashboard Integration

library(shiny)
library(ggplot2)

ui <- fluidPage(
  titlePanel("Oil Price Dashboard"),

  sidebarLayout(
    sidebarPanel(
      selectInput("commodity", "Select Commodity:",
                  choices = c("WTI_USD", "BRENT_CRUDE_USD", "NATURAL_GAS_USD")),
      selectInput("days", "Time Period:",
                  choices = c("7" = 7, "30" = 30, "90" = 90)),
      actionButton("refresh", "Refresh Data")
    ),

    mainPanel(
      h4(textOutput("current_price")),
      plotOutput("price_chart"),
      tableOutput("statistics")
    )
  )
)

server <- function(input, output, session) {
  client <- create_client()

  price_data <- reactive({
    input$refresh  # Trigger on button click
    get_historical_prices(client, input$commodity, as.numeric(input$days))
  })

  output$current_price <- renderText({
    prices <- get_latest_prices(client, input$commodity)
    paste("Current Price:", prices$formatted[1])
  })

  output$price_chart <- renderPlot({
    ggplot(price_data(), aes(x = created_at, y = price)) +
      geom_line(color = "steelblue", linewidth = 1) +
      labs(title = paste(input$commodity, "Price History"),
           x = "Date", y = "Price (USD)") +
      theme_minimal()
  })

  output$statistics <- renderTable({
    data <- price_data()
    data.frame(
      Metric = c("Mean", "Min", "Max", "Std Dev"),
      Value = c(
        round(mean(data$price), 2),
        round(min(data$price), 2),
        round(max(data$price), 2),
        round(sd(data$price), 2)
      )
    )
  })
}

shinyApp(ui, server)

Time Series Forecasting

library(forecast)
library(tseries)

client <- create_client()

# Get 90 days of historical data
history <- get_historical_prices(client, "WTI_USD", days = 90)

# Create time series object
ts_data <- ts(history$price, frequency = 7)  # Weekly seasonality

# Fit ARIMA model
model <- auto.arima(ts_data)
summary(model)

# Forecast next 14 days
forecast_result <- forecast(model, h = 14)

# Plot forecast
plot(forecast_result,
     main = "WTI Price Forecast",
     xlab = "Time",
     ylab = "Price (USD)")

Error Handling

#' Fetch prices with retry logic
#'
#' @param client Client configuration
#' @param codes Commodity codes
#' @param max_retries Maximum retry attempts
#' @return Data frame with prices
fetch_with_retry <- function(client, codes, max_retries = 3) {
  for (attempt in 1:max_retries) {
    tryCatch({
      return(get_latest_prices(client, codes))
    }, error = function(e) {
      if (grepl("Rate limit", e$message)) {
        backoff <- 2^attempt
        message(sprintf("Rate limited, waiting %d seconds (attempt %d/%d)",
                        backoff, attempt, max_retries))
        Sys.sleep(backoff)
      } else if (grepl("Authentication", e$message)) {
        stop(e)  # Don't retry auth errors
      } else {
        message(sprintf("Error: %s (attempt %d/%d)", e$message, attempt, max_retries))
        Sys.sleep(1)
      }

      if (attempt == max_retries) {
        stop(paste("Failed after", max_retries, "attempts:", e$message))
      }
    })
  }
}

# Usage
tryCatch({
  prices <- fetch_with_retry(client, "WTI_USD")
  print(prices)
}, error = function(e) {
  message("Failed to fetch prices: ", e$message)
})

Best Practices

Environment Configuration

# .Renviron file (in project root or home directory)
# OILPRICE_API_KEY=opa_live_your_key_here

# Load in script
if (Sys.getenv("OILPRICE_API_KEY") == "") {
  stop("Please set OILPRICE_API_KEY environment variable")
}

Caching Results

library(memoise)

# Create cached version of API functions
cached_get_prices <- memoise(get_latest_prices, ~timeout(300))  # 5 min cache

# Usage - subsequent calls use cached data
prices1 <- cached_get_prices(client, "WTI_USD")  # API call
prices2 <- cached_get_prices(client, "WTI_USD")  # From cache

Rate Limiting

#' Rate-limited API request wrapper
#'
#' @param func Function to call
#' @param ... Arguments to pass to function
#' @param min_interval Minimum seconds between calls
rate_limited <- function(func, ..., min_interval = 1) {
  last_call <- getOption("oilprice_last_call", 0)
  current_time <- as.numeric(Sys.time())

  wait_time <- min_interval - (current_time - last_call)
  if (wait_time > 0) {
    Sys.sleep(wait_time)
  }

  options(oilprice_last_call = as.numeric(Sys.time()))
  func(...)
}

Common Commodity Codes

CodeDescription
WTI_USDWest Texas Intermediate Crude Oil
BRENT_CRUDE_USDBrent Crude Oil
NATURAL_GAS_USDNatural Gas (Henry Hub)
HEATING_OIL_USDHeating Oil No. 2
DIESEL_USDUltra Low Sulfur Diesel

Next Steps

  • Authentication Guide - API key management
  • API Reference - Complete endpoint documentation
  • Historical Data - Time-series queries
  • Rate Limiting - Usage limits and best practices
Last Updated: 12/28/25, 12:24 AM