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

C# / .NET Integration Guide

Integrate OilPriceAPI into your .NET applications to access real-time crude oil prices, Brent crude data, natural gas rates, and commodity market information for enterprise energy applications.

Requirements

  • .NET 6.0 or higher (also compatible with .NET Framework 4.7.2+)
  • System.Text.Json or Newtonsoft.Json

Installation

Using NuGet Package Manager:

dotnet add package System.Text.Json
# Optional: for more flexible JSON handling
dotnet add package Newtonsoft.Json

Quick Start

using System.Net.Http;
using System.Text.Json;

var apiKey = Environment.GetEnvironmentVariable("OILPRICE_API_KEY");
using var client = new HttpClient();

client.DefaultRequestHeaders.Add("Authorization", $"Token {apiKey}");

var response = await client.GetAsync(
    "https://api.oilpriceapi.com/v1/prices/latest?by_code=WTI_USD"
);

var json = await response.Content.ReadAsStringAsync();
Console.WriteLine(json);

Complete API Client Class

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace OilPriceAPI
{
    public class PriceData
    {
        [JsonPropertyName("price")]
        public decimal Price { get; set; }

        [JsonPropertyName("formatted")]
        public string Formatted { get; set; }

        [JsonPropertyName("currency")]
        public string Currency { get; set; }

        [JsonPropertyName("code")]
        public string Code { get; set; }

        [JsonPropertyName("created_at")]
        public DateTime CreatedAt { get; set; }
    }

    public class PriceResponse
    {
        [JsonPropertyName("status")]
        public string Status { get; set; }

        [JsonPropertyName("data")]
        public Dictionary<string, PriceData> Data { get; set; }
    }

    public class HistoricalResponse
    {
        [JsonPropertyName("status")]
        public string Status { get; set; }

        [JsonPropertyName("data")]
        public List<PriceData> Data { get; set; }
    }

    public class OilPriceAPIException : Exception
    {
        public int StatusCode { get; }

        public OilPriceAPIException(string message, int statusCode = 0)
            : base(message)
        {
            StatusCode = statusCode;
        }
    }

    public class RateLimitException : OilPriceAPIException
    {
        public RateLimitException() : base("Rate limit exceeded", 429) { }
    }

    public class AuthenticationException : OilPriceAPIException
    {
        public AuthenticationException() : base("Invalid API key", 401) { }
    }

    public class OilPriceClient : IDisposable
    {
        private readonly HttpClient _httpClient;
        private readonly string _baseUrl = "https://api.oilpriceapi.com/v1";
        private readonly JsonSerializerOptions _jsonOptions;

        public OilPriceClient(string apiKey = null)
        {
            apiKey ??= Environment.GetEnvironmentVariable("OILPRICE_API_KEY");

            if (string.IsNullOrEmpty(apiKey))
                throw new ArgumentException("API key is required");

            _httpClient = new HttpClient
            {
                Timeout = TimeSpan.FromSeconds(30)
            };
            _httpClient.DefaultRequestHeaders.Add("Authorization", $"Token {apiKey}");
            _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");

            _jsonOptions = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            };
        }

        private async Task<T> RequestAsync<T>(string endpoint, Dictionary<string, string> parameters = null)
        {
            var url = $"{_baseUrl}{endpoint}";

            if (parameters?.Count > 0)
            {
                var queryString = string.Join("&",
                    parameters.Select(p => $"{p.Key}={Uri.EscapeDataString(p.Value)}"));
                url = $"{url}?{queryString}";
            }

            var response = await _httpClient.GetAsync(url);

            switch ((int)response.StatusCode)
            {
                case 401:
                    throw new AuthenticationException();
                case 429:
                    throw new RateLimitException();
                case int code when code >= 400:
                    throw new OilPriceAPIException($"API error: {response.StatusCode}", code);
            }

            var content = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<T>(content, _jsonOptions);
        }

        public async Task<PriceResponse> GetLatestPricesAsync(params string[] codes)
        {
            var parameters = new Dictionary<string, string>
            {
                { "by_code", string.Join(",", codes) }
            };

            return await RequestAsync<PriceResponse>("/prices/latest", parameters);
        }

        public async Task<HistoricalResponse> GetHistoricalPricesAsync(string code, int days = 7)
        {
            var parameters = new Dictionary<string, string>
            {
                { "by_code", code }
            };

            return await RequestAsync<HistoricalResponse>($"/prices/past_{days}_days", parameters);
        }

        public void Dispose()
        {
            _httpClient?.Dispose();
        }
    }
}

Usage Examples

Fetch Multiple Commodities

using OilPriceAPI;

using var client = new OilPriceClient();

// Get multiple oil prices
var prices = await client.GetLatestPricesAsync(
    "WTI_USD", "BRENT_CRUDE_USD", "NATURAL_GAS_USD"
);

foreach (var (code, data) in prices.Data)
{
    Console.WriteLine($"{code}: {data.Formatted}");
}

Historical Price Analysis

using OilPriceAPI;

using var client = new OilPriceClient();

// Get past week of WTI prices
var history = await client.GetHistoricalPricesAsync("WTI_USD", days: 7);

Console.WriteLine("WTI Price History:");
foreach (var point in history.Data)
{
    Console.WriteLine($"  {point.CreatedAt:yyyy-MM-dd}: ${point.Price:F2}");
}

// Calculate statistics
var prices = history.Data.Select(p => p.Price).ToList();
var average = prices.Average();
var min = prices.Min();
var max = prices.Max();

Console.WriteLine($"\nStatistics:");
Console.WriteLine($"  Average: ${average:F2}");
Console.WriteLine($"  Range: ${min:F2} - ${max:F2}");

ASP.NET Core Integration

// Program.cs
builder.Services.AddSingleton<OilPriceClient>(sp =>
    new OilPriceClient(builder.Configuration["OilPriceAPI:ApiKey"])
);

// appsettings.json
{
    "OilPriceAPI": {
        "ApiKey": "${OILPRICE_API_KEY}"
    }
}

// Services/OilPriceService.cs
public class OilPriceService
{
    private readonly OilPriceClient _client;
    private readonly IMemoryCache _cache;

    public OilPriceService(OilPriceClient client, IMemoryCache cache)
    {
        _client = client;
        _cache = cache;
    }

    public async Task<PriceResponse> GetCurrentPricesAsync(params string[] codes)
    {
        var cacheKey = $"oil_prices_{string.Join("_", codes.OrderBy(c => c))}";

        return await _cache.GetOrCreateAsync(cacheKey, async entry =>
        {
            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5);
            return await _client.GetLatestPricesAsync(codes);
        });
    }
}

// Controllers/PricesController.cs
[ApiController]
[Route("api/[controller]")]
public class PricesController : ControllerBase
{
    private readonly OilPriceService _oilService;

    public PricesController(OilPriceService oilService)
    {
        _oilService = oilService;
    }

    [HttpGet]
    public async Task<IActionResult> GetPrices([FromQuery] string codes = "WTI_USD")
    {
        try
        {
            var codeArray = codes.Split(',');
            var prices = await _oilService.GetCurrentPricesAsync(codeArray);
            return Ok(prices);
        }
        catch (OilPriceAPIException ex)
        {
            return StatusCode(ex.StatusCode, new { error = ex.Message });
        }
    }
}

Concurrent Requests

using OilPriceAPI;

using var client = new OilPriceClient();

var commodities = new[] { "WTI_USD", "BRENT_CRUDE_USD", "NATURAL_GAS_USD", "HEATING_OIL_USD" };

// Fetch all prices concurrently
var tasks = commodities.Select(async code =>
{
    var price = await client.GetLatestPricesAsync(code);
    return (code, price);
});

var results = await Task.WhenAll(tasks);

foreach (var (code, response) in results)
{
    if (response.Data.TryGetValue(code, out var data))
    {
        Console.WriteLine($"{code}: {data.Formatted}");
    }
}

Blazor Component

@page "/prices"
@inject OilPriceClient OilClient

<h3>Current Oil Prices</h3>

@if (_loading)
{
    <p>Loading prices...</p>
}
else if (_error != null)
{
    <p class="text-danger">@_error</p>
}
else if (_prices != null)
{
    <table class="table">
        <thead>
            <tr>
                <th>Commodity</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var (code, data) in _prices.Data)
            {
                <tr>
                    <td>@code</td>
                    <td>@data.Formatted</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private PriceResponse _prices;
    private bool _loading = true;
    private string _error;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            _prices = await OilClient.GetLatestPricesAsync(
                "WTI_USD", "BRENT_CRUDE_USD", "NATURAL_GAS_USD"
            );
        }
        catch (Exception ex)
        {
            _error = ex.Message;
        }
        finally
        {
            _loading = false;
        }
    }
}

Error Handling

public static class RetryHelper
{
    public static async Task<T> ExecuteWithRetryAsync<T>(
        Func<Task<T>> operation,
        int maxRetries = 3,
        int baseDelayMs = 1000)
    {
        Exception lastException = null;

        for (int attempt = 0; attempt <= maxRetries; attempt++)
        {
            try
            {
                return await operation();
            }
            catch (RateLimitException ex)
            {
                lastException = ex;
                if (attempt < maxRetries)
                {
                    var delay = baseDelayMs * (int)Math.Pow(2, attempt);
                    Console.WriteLine($"Rate limited, waiting {delay}ms (attempt {attempt + 1}/{maxRetries})");
                    await Task.Delay(delay);
                }
            }
            catch (AuthenticationException)
            {
                throw; // Don't retry auth errors
            }
            catch (OilPriceAPIException ex)
            {
                lastException = ex;
                if (attempt < maxRetries)
                {
                    await Task.Delay(baseDelayMs);
                }
            }
        }

        throw lastException;
    }
}

// Usage
var prices = await RetryHelper.ExecuteWithRetryAsync(
    () => client.GetLatestPricesAsync("WTI_USD")
);

Best Practices

Configuration with IOptions

public class OilPriceApiOptions
{
    public string ApiKey { get; set; }
    public int TimeoutSeconds { get; set; } = 30;
    public int CacheMinutes { get; set; } = 5;
}

// appsettings.json
{
    "OilPriceApi": {
        "ApiKey": "${OILPRICE_API_KEY}",
        "TimeoutSeconds": 30,
        "CacheMinutes": 5
    }
}

// Program.cs
builder.Services.Configure<OilPriceApiOptions>(
    builder.Configuration.GetSection("OilPriceApi")
);

Dependency Injection

public interface IOilPriceClient
{
    Task<PriceResponse> GetLatestPricesAsync(params string[] codes);
    Task<HistoricalResponse> GetHistoricalPricesAsync(string code, int days = 7);
}

// Register in DI container
builder.Services.AddSingleton<IOilPriceClient, OilPriceClient>();

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