Go / Golang Integration Guide
Integrate OilPriceAPI into your Go applications to access the latest available crude oil prices, Brent crude data, natural gas rates, and commodity market information. Build high-performance solutions for commodities trading, logistics, and fleet management systems.
Official Go SDK
Add the current compatible release of the official OilPriceAPI Go module:
go get github.com/OilpriceAPI/oilpriceapi-go
The direct REST examples below use only Go's standard library, which is also a supported integration path.
# Initialize your Go module (if not already done)
go mod init your-project-name
Quick Start
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
apiKey := os.Getenv("OILPRICEAPI_KEY")
req, _ := http.NewRequest("GET", "https://api.oilpriceapi.com/v1/prices/latest?by_code=WTI_USD", nil)
req.Header.Set("Authorization", "Token "+apiKey)
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Printf("Request failed: %v\n", err)
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
Complete API Client
Create a reusable client for all OilPriceAPI endpoints:
package oilpriceapi
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
// Client handles API communication
type Client struct {
APIKey string
BaseURL string
HTTPClient *http.Client
}
// PriceData represents commodity price information
type PriceData struct {
Price float64 `json:"price"`
Formatted string `json:"formatted"`
Currency string `json:"currency"`
Code string `json:"code"`
CreatedAt string `json:"created_at"`
}
// PriceResponse represents a single-commodity latest response.
// For by_code=WTI_USD the API returns a flat object at `data`.
type PriceResponse struct {
Status string `json:"status"`
Data PriceData `json:"data"`
}
// HistoricalData wraps the `prices` array returned by historical endpoints.
type HistoricalData struct {
Prices []PriceData `json:"prices"`
}
// HistoricalResponse for time-series data
type HistoricalResponse struct {
Status string `json:"status"`
Data HistoricalData `json:"data"`
}
// NewClient creates an OilPriceAPI client
func NewClient(apiKey string) *Client {
if apiKey == "" {
apiKey = os.Getenv("OILPRICEAPI_KEY")
}
return &Client{
APIKey: apiKey,
BaseURL: "https://api.oilpriceapi.com/v1",
HTTPClient: &http.Client{
Timeout: 30 * time.Second,
},
}
}
// request performs authenticated API calls
func (c *Client) request(endpoint string, params map[string]string) ([]byte, error) {
u, _ := url.Parse(c.BaseURL + endpoint)
q := u.Query()
for k, v := range params {
q.Set(k, v)
}
u.RawQuery = q.Encode()
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return nil, fmt.Errorf("creating request: %w", err)
}
req.Header.Set("Authorization", "Token "+c.APIKey)
req.Header.Set("Content-Type", "application/json")
resp, err := c.HTTPClient.Do(req)
if err != nil {
return nil, fmt.Errorf("executing request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode == 401 {
return nil, fmt.Errorf("invalid API key")
}
if resp.StatusCode == 429 {
return nil, fmt.Errorf("rate limit exceeded")
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("API error: status %d", resp.StatusCode)
}
return io.ReadAll(resp.Body)
}
// GetLatestPrice fetches current commodity prices
func (c *Client) GetLatestPrice(codes string) (*PriceResponse, error) {
body, err := c.request("/prices/latest", map[string]string{"by_code": codes})
if err != nil {
return nil, err
}
var result PriceResponse
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("parsing response: %w", err)
}
return &result, nil
}
// GetPastWeekPrices fetches the previous seven days of price history.
func (c *Client) GetPastWeekPrices(code string) (*HistoricalResponse, error) {
body, err := c.request("/prices/past_week", map[string]string{"by_code": code})
if err != nil {
return nil, err
}
var result HistoricalResponse
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("parsing response: %w", err)
}
return &result, nil
}
Usage Examples
Fetch Multiple Commodity Prices
package main
import (
"fmt"
"log"
)
func main() {
client := oilpriceapi.NewClient("")
// Fetch WTI, Brent, and Natural Gas prices
codes := []string{"WTI_USD", "BRENT_CRUDE_USD", "NATURAL_GAS_USD"}
for _, code := range codes {
resp, err := client.GetLatestPrice(code)
if err != nil {
log.Fatalf("Failed to fetch %s: %v", code, err)
}
fmt.Printf("%s: %s\n", resp.Data.Code, resp.Data.Formatted)
}
}
Historical Data Analysis
package main
import (
"fmt"
"log"
)
func main() {
client := oilpriceapi.NewClient("")
history, err := client.GetPastWeekPrices("WTI_USD")
if err != nil {
log.Fatalf("Failed to fetch history: %v", err)
}
fmt.Println("WTI Price History (Past Week):")
for _, point := range history.Data.Prices {
fmt.Printf(" %s: $%.2f\n", point.CreatedAt, point.Price)
}
}
Concurrent Requests with Goroutines
package main
import (
"fmt"
"sync"
)
func main() {
client := oilpriceapi.NewClient("")
commodities := []string{"WTI_USD", "BRENT_CRUDE_USD", "DUBAI_CRUDE_USD"}
var wg sync.WaitGroup
results := make(chan string, len(commodities))
for _, code := range commodities {
wg.Add(1)
go func(c string) {
defer wg.Done()
price, err := client.GetLatestPrice(c)
if err != nil {
results <- fmt.Sprintf("%s: error - %v", c, err)
return
}
results <- fmt.Sprintf("%s: %s", c, price.Data.Formatted)
}(code)
}
go func() {
wg.Wait()
close(results)
}()
for result := range results {
fmt.Println(result)
}
}
Error Handling
Implement robust error handling with retries:
package main
import (
"fmt"
"time"
)
func fetchWithRetry(client *oilpriceapi.Client, code string, maxRetries int) (*oilpriceapi.PriceResponse, error) {
var lastErr error
for i := 0; i < maxRetries; i++ {
price, err := client.GetLatestPrice(code)
if err == nil {
return price, nil
}
lastErr = err
// Exponential backoff
backoff := time.Duration(1<<uint(i)) * time.Second
fmt.Printf("Attempt %d failed, retrying in %v: %v\n", i+1, backoff, err)
time.Sleep(backoff)
}
return nil, fmt.Errorf("all %d attempts failed: %w", maxRetries, lastErr)
}
func main() {
client := oilpriceapi.NewClient("")
price, err := fetchWithRetry(client, "WTI_USD", 3)
if err != nil {
fmt.Printf("Failed: %v\n", err)
return
}
fmt.Printf("Success: %+v\n", price)
}
Best Practices
Environment Configuration
// Use environment variables for API keys
apiKey := os.Getenv("OILPRICEAPI_KEY")
if apiKey == "" {
log.Fatal("OILPRICEAPI_KEY environment variable not set")
}
Connection Pooling
// Reuse HTTP client for connection pooling
var defaultClient = &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}
Context Support
import "context"
func (c *Client) RequestWithContext(ctx context.Context, endpoint string) ([]byte, error) {
req, _ := http.NewRequestWithContext(ctx, "GET", c.BaseURL+endpoint, nil)
req.Header.Set("Authorization", "Token "+c.APIKey)
resp, err := c.HTTPClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
Common Commodity Codes
| Code | Description |
|---|---|
WTI_USD | West Texas Intermediate Crude Oil |
BRENT_CRUDE_USD | Brent Crude Oil |
NATURAL_GAS_USD | Natural Gas (Henry Hub) |
HEATING_OIL_USD | Heating Oil No. 2 |
DIESEL_USD | Ultra Low Sulfur Diesel |
Frequently Asked Questions
Is there an official SDK for Go?
Yes. Install the official module with go get github.com/OilpriceAPI/oilpriceapi-go. The standard-library REST examples above remain available when you do not want an SDK dependency.
How do I handle rate limiting in Go?
Implement exponential backoff when you receive 429 (Too Many Requests) responses. Use time.Sleep() with increasing delays between retries:
backoff := time.Duration(1<<uint(attempt)) * time.Second
time.Sleep(backoff)
What's the recommended error handling approach?
Always check HTTP status codes before parsing responses. Handle network timeouts and implement proper retry logic for transient failures. Use Go's error interface to wrap and propagate errors with context using fmt.Errorf("context: %w", err).
Can I use async/concurrent requests?
Yes, Go excels at concurrency. Use goroutines with sync.WaitGroup to fetch multiple commodity prices in parallel. The example in the "Concurrent Requests with Goroutines" section demonstrates this pattern with channels for collecting results.
Related Resources
- Power BI Integration - No-code dashboard alternative
- Looker Integration - Google ecosystem analytics
- Zapier Integration - Automate without coding
- Commodities Trading API - Trading platform integration
- Maritime Bunker API - Marine fuel applications
- Logistics Fuel API - Supply chain systems
- C# Developer Guide - Alternative language guide
- Ruby Developer Guide - Alternative language guide
- Authentication Guide - API key management
- API Reference - Complete endpoint documentation
- WebSocket Streaming - Streaming price updates