Skip to main content

Gas Oracle API

The Gas Oracle provides real-time gas prices with multi-provider failover, designed for MEV bots and trading applications that need reliable gas data even during RPC outages.

Key Features

  • No authentication required - Public endpoints for easy integration
  • Multi-provider failover - Automatic fallback when primary fails
  • Stale data serving - Returns cached data when all providers are down
  • EIP-1559 support - Base fee, priority fee, and max fee calculations
  • Network congestion - Real-time congestion level assessment
  • LRT rates - Liquid restaking token exchange rates
  • Beacon chain status - Validator and sync information

Endpoints

Get Gas Prices

GET /v1/oracle/gas/{chain}

Returns current gas prices at different priority levels.

Supported chains: Ethereum, Polygon, Arbitrum, Optimism, Base, Avalanche

Request

curl https://api.axol.io/api/v1/oracle/gas/ethereum

Response

{
"chain": "ethereum",
"block_number": 19500000,
"timestamp": "2026-01-15T10:30:00Z",
"source": "primary",
"stale": false,
"ttl_seconds": 3,
"base_fee_gwei": 25.0,
"slow": {
"base_fee_gwei": 25.0,
"priority_fee_gwei": 1.6,
"max_fee_gwei": 26.6
},
"standard": {
"base_fee_gwei": 25.0,
"priority_fee_gwei": 2.0,
"max_fee_gwei": 27.0
},
"fast": {
"base_fee_gwei": 25.0,
"priority_fee_gwei": 3.0,
"max_fee_gwei": 28.0
},
"instant": {
"base_fee_gwei": 25.0,
"priority_fee_gwei": 5.0,
"max_fee_gwei": 30.0
},
"network_congestion": "medium",
"provider_status": "healthy",
"failover_active": false
}

Response Fields

FieldTypeDescription
chainstringBlockchain identifier
block_numberintegerBlock number at time of query
timestampstringISO 8601 timestamp
sourcestringData source (primary, backup, cache)
stalebooleanTrue if data is from cache due to provider failure
ttl_secondsintegerSeconds until data should be refreshed
base_fee_gweifloatCurrent base fee in gwei
slowobjectLow priority tier (~5 min confirmation)
standardobjectNormal priority (~2-3 min confirmation)
fastobjectHigh priority (~1 min confirmation)
instantobjectMaximum priority (under 30s confirmation)
network_congestionstringlow, medium, high, or critical
provider_statusstringhealthy, degraded, or unavailable
failover_activebooleanTrue if using backup provider

Priority Tier Details

Each tier contains:

  • base_fee_gwei: Current base fee
  • priority_fee_gwei: Recommended priority fee (tip)
  • max_fee_gwei: Recommended max fee (base + priority)

Get LRT Exchange Rates

GET /v1/oracle/lrt/rates

Returns exchange rates for Liquid Restaking Tokens relative to ETH.

Supported tokens: weETH, stETH, wstETH, rETH, cbETH, ezETH, rsETH (see constants for full list)

Request

# Get all rates
curl https://api.axol.io/api/v1/oracle/lrt/rates

# Filter to specific tokens
curl "https://api.axol.io/api/v1/oracle/lrt/rates?tokens=weETH,stETH"

Response

{
"timestamp": "2026-01-15T10:30:00Z",
"source": "primary",
"stale": false,
"ttl_seconds": 30,
"rates": {
"weETH": {
"token": "weETH",
"rate": 1.05,
"rate_wei": "1050000000000000000",
"inverse_rate": 0.952,
"protocol": "EtherFi"
},
"stETH": {
"token": "stETH",
"rate": 1.0,
"rate_wei": "1000000000000000000",
"inverse_rate": 1.0,
"protocol": "Lido"
},
"wstETH": {
"token": "wstETH",
"rate": 1.17,
"rate_wei": "1170000000000000000",
"inverse_rate": 0.855,
"protocol": "Lido"
},
"rETH": {
"token": "rETH",
"rate": 1.10,
"rate_wei": "1100000000000000000",
"inverse_rate": 0.909,
"protocol": "RocketPool"
},
"cbETH": {
"token": "cbETH",
"rate": 1.06,
"rate_wei": "1060000000000000000",
"inverse_rate": 0.943,
"protocol": "Coinbase"
}
},
"eth_price_usd": 3500.00
}

Get Beacon Chain Status

GET /v1/oracle/beacon/status

Returns beacon chain synchronization status and validator information.

Response

{
"timestamp": "2026-01-15T10:30:00Z",
"source": "primary",
"stale": false,
"ttl_seconds": 12,
"sync_status": "synced",
"sync_distance": 0,
"slot": {
"slot": 8500000,
"epoch": 265625,
"finalized_epoch": 265622,
"justified_epoch": 265623
},
"validators": {
"total_validators": 1000000,
"pending_validators": 0,
"exiting_validators": 0
},
"network": "mainnet"
}

Get Oracle Health

GET /v1/oracle/health

Returns health status of all oracle providers.

Response

{
"overall_status": "healthy",
"timestamp": "2026-01-15T10:30:00Z",
"providers": {
"ethereum": {
"primary": {"status": "healthy", "success_rate": 0.99, "latency_ms": 45},
"backup": {"status": "healthy", "success_rate": 0.98, "latency_ms": 120}
},
"polygon": {
"primary": {"status": "healthy", "success_rate": 0.99, "latency_ms": 38},
"backup": {"status": "degraded", "success_rate": 0.85, "latency_ms": 250}
}
}
}

Clear Oracle Cache

POST /v1/oracle/cache/clear

Clears cached oracle data. Useful for forcing fresh data after detecting issues.

Request

# Clear all caches
curl -X POST https://api.axol.io/api/v1/oracle/cache/clear

# Clear specific chain
curl -X POST "https://api.axol.io/api/v1/oracle/cache/clear?chain=ethereum"

Code Examples

Python - Gas Oracle with Retry

import requests
from typing import Optional

class GasOracle:
def __init__(self, base_url: str = "https://api.axol.io/api/v1"):
self.base_url = base_url

def get_gas(self, chain: str = "ethereum") -> dict:
"""Get gas prices with automatic retry."""
response = requests.get(
f"{self.base_url}/oracle/gas/{chain}",
timeout=5
)
response.raise_for_status()
return response.json()

def get_safe_gas_price(
self,
chain: str = "ethereum",
tier: str = "fast",
stale_buffer: float = 1.2
) -> float:
"""Get gas price with safety buffer for stale data."""
data = self.get_gas(chain)

price = data[tier]["max_fee_gwei"]

# Add buffer if data is stale
if data.get("stale"):
price *= stale_buffer

return price

def should_trade(self, chain: str = "ethereum", max_gas_gwei: float = 50) -> bool:
"""Check if gas is low enough to trade."""
data = self.get_gas(chain)
return data["fast"]["max_fee_gwei"] <= max_gas_gwei

# Usage
oracle = GasOracle()
gas = oracle.get_gas("ethereum")
print(f"Fast gas: {gas['fast']['max_fee_gwei']} gwei")
print(f"Congestion: {gas['network_congestion']}")

if oracle.should_trade(max_gas_gwei=30):
print("Gas is low - good time to trade!")

TypeScript - Gas Oracle

interface GasPrice {
base_fee_gwei: number;
priority_fee_gwei: number;
max_fee_gwei: number;
}

interface GasOracleResponse {
chain: string;
slow: GasPrice;
standard: GasPrice;
fast: GasPrice;
instant: GasPrice;
network_congestion: 'low' | 'medium' | 'high' | 'critical';
stale: boolean;
}

class GasOracle {
private baseUrl: string;

constructor(baseUrl = 'https://api.axol.io/api/v1') {
this.baseUrl = baseUrl;
}

async getGas(chain = 'ethereum'): Promise<GasOracleResponse> {
const response = await fetch(`${this.baseUrl}/oracle/gas/${chain}`);
if (!response.ok) throw new Error(`Gas oracle failed: ${response.status}`);
return response.json();
}

async waitForLowGas(
chain: string,
maxGwei: number,
checkIntervalMs = 5000
): Promise<GasOracleResponse> {
while (true) {
const gas = await this.getGas(chain);
if (gas.fast.max_fee_gwei <= maxGwei) {
return gas;
}
await new Promise(r => setTimeout(r, checkIntervalMs));
}
}
}

// Usage
const oracle = new GasOracle();
const gas = await oracle.getGas('ethereum');
console.log(`Fast: ${gas.fast.max_fee_gwei} gwei`);

// Wait for low gas
const lowGas = await oracle.waitForLowGas('ethereum', 25);
console.log('Gas is low, executing trade...');

Python - LRT Arbitrage Detection

import requests

def check_lrt_arbitrage(
base_url: str = "https://api.axol.io/api/v1",
min_spread_percent: float = 0.5
) -> list[dict]:
"""Check for LRT arbitrage opportunities."""
response = requests.get(f"{base_url}/oracle/lrt/rates")
data = response.json()

opportunities = []

for token, info in data["rates"].items():
rate = info["rate"]
inverse = info["inverse_rate"]

# Check if rate deviates significantly from 1.0
# (Could indicate arbitrage opportunity)
deviation = abs(rate - 1.0) / 1.0 * 100

if deviation > min_spread_percent:
opportunities.append({
"token": token,
"rate": rate,
"deviation_percent": deviation,
"protocol": info["protocol"]
})

return opportunities

# Usage
arbs = check_lrt_arbitrage(min_spread_percent=2.0)
for arb in arbs:
print(f"{arb['token']}: {arb['rate']:.4f} ({arb['deviation_percent']:.2f}% deviation)")

Error Handling

Common Errors

StatusErrorResolution
400invalid_chainUse supported chain (ethereum, polygon, etc.)
503service_unavailableAll providers failed, try again later

Handling Stale Data

gas = oracle.get_gas("ethereum")

if gas["stale"]:
# Data is from cache - providers are down
logger.warning(f"Using stale gas data from {gas['source']}")

# Option 1: Add safety buffer
gas_price = gas["fast"]["max_fee_gwei"] * 1.3

# Option 2: Skip non-critical operations
if not is_critical_trade:
return

# Option 3: Use alternative data source
gas_price = get_backup_gas_price()

Best Practices

1. Cache Client-Side

Even though the API caches, reduce your request volume:

from functools import lru_cache
import time

@lru_cache(maxsize=10)
def get_cached_gas(chain: str, ttl_bucket: int) -> dict:
return oracle.get_gas(chain)

def get_gas_with_local_cache(chain: str, cache_seconds: int = 3) -> dict:
ttl_bucket = int(time.time() / cache_seconds)
return get_cached_gas(chain, ttl_bucket)

2. Use Appropriate Tier

ScenarioRecommended Tier
Arbitrage (time-sensitive)instant
Liquidationfast
Regular swapstandard
Non-urgent transferslow

3. Monitor Congestion

gas = oracle.get_gas("ethereum")

if gas["network_congestion"] == "critical":
# Skip non-essential operations
logger.info("Network congested, deferring trade")
return

if gas["network_congestion"] in ("low", "medium"):
# Good conditions for trading
execute_trade(gas_price=gas["fast"]["max_fee_gwei"])

See Also