Blocknative Gas API Migration Guide

Shuts down June 19, 2026

Migrating production callers from Blocknative's sunsetting Gas Platform API takes about 5-30 minutes depending on how deeply your code is coupled to Blocknative's response shape. This guide is the step-by-step walkthrough: before/after code in four languages, the confidence-level mapping you need, the common gotchas, and a production-readiness checklist. For the high-level pitch and shutdown context, see the Blocknative alternative landing page. For the full field-by-field mapping, see the field mapping reference.

TL;DR — the one-line migration

If you only ever call api.blocknative.com/gasprices/blockprices?confidenceLevels=99 and read blockPrices[0].estimatedPrices[0].price:

// Before — Blocknative
const res = await fetch(
  'https://api.blocknative.com/gasprices/blockprices?confidenceLevels=99',
  { headers: { Authorization: process.env.BLOCKNATIVE_API_KEY } }
)
const gwei = (await res.json()).blockPrices[0].estimatedPrices[0].price

// After — Gas Fee Predictor (no key, no auth header)
const res = await fetch('https://api.gasfeepredictor.com/api/gas-predictions')
const gwei = (await res.json()).current.high  // "will-include" tier ≈ BN 99%

That's the whole migration for the simple case. The rest of this guide covers multi-tier callers, EIP-1559 max-fee handling, predictions, and language-specific patterns.

Step-by-step migration

1. Identify which Blocknative response fields you actually use

Most callers only use 1-2 fields from Blocknative's response. Grep your codebase for these keys:

grep -rn "blockPrices\|estimatedPrices\|baseFeePerGas\|maxFeePerGas\|maxPriorityFeePerGas\|currentBlockNumber\|msSinceLastBlock" .

Most apps use just estimatedPrices[].price at one confidence level. If that's you, jump to step 3 — your migration is the one-line swap above.

2. Pick the right replacement endpoint

Use this decision table:

Your use caseReplacement endpoint
Just current gas price (any tier)/api/gas-predictions
Gas + forecast in one call/api/gas-predictions or /api/dashboard
Gas + ETH/USD price in one call/api/dashboard
Historical gas series/api/gas-history?range=1d
L2 gas (Arbitrum, Optimism, Base, Polygon)/api/l2-gas (BN was L1-only — bonus)
Mempool monitoringNot covered — try Alchemy, Tenderly, Bloxroute

3. Map confidence percentiles to tiers

Blocknative returns gas prices at five confidence percentiles. We collapse them to three tiers. Use this mapping:

Blocknative confidenceClosest GFP tierUse case
99%current.high“Will include” — pay slightly more for guaranteed fast inclusion
95%current.highApproximately same as 99% in practice
90%current.averageTypical wallet default — fast inclusion expected
80%current.averageStandard tier — most wallets' default
70%current.lowSlow inclusion — may take multiple blocks

Before / after in four languages

JavaScript / Node 18+

// Before
const res = await fetch(
  'https://api.blocknative.com/gasprices/blockprices?confidenceLevels=99,90,70',
  { headers: { Authorization: process.env.BLOCKNATIVE_API_KEY } }
)
const block = (await res.json()).blockPrices[0]
const fast = block.estimatedPrices.find(p => p.confidence === 99).price
const standard = block.estimatedPrices.find(p => p.confidence === 90).price
const slow = block.estimatedPrices.find(p => p.confidence === 70).price

// After — no API key, simpler shape
const res = await fetch('https://api.gasfeepredictor.com/api/gas-predictions')
const { current } = await res.json()
const fast = current.high
const standard = current.average
const slow = current.low

Python

# Before
import os, requests
headers = {'Authorization': os.environ['BLOCKNATIVE_API_KEY']}
r = requests.get(
    'https://api.blocknative.com/gasprices/blockprices?confidenceLevels=99,90,70',
    headers=headers, timeout=5
)
block = r.json()['blockPrices'][0]
fast = next(p['price'] for p in block['estimatedPrices'] if p['confidence'] == 99)
standard = next(p['price'] for p in block['estimatedPrices'] if p['confidence'] == 90)
slow = next(p['price'] for p in block['estimatedPrices'] if p['confidence'] == 70)

# After — no API key, no headers
import requests
data = requests.get('https://api.gasfeepredictor.com/api/gas-predictions', timeout=5).json()
fast, standard, slow = data['current']['high'], data['current']['average'], data['current']['low']

curl + jq (shell scripts, cron jobs)

# Before
curl -H "Authorization: $BLOCKNATIVE_API_KEY" \
  "https://api.blocknative.com/gasprices/blockprices?confidenceLevels=99" \
  | jq '.blockPrices[0].estimatedPrices[0].price'

# After
curl -s "https://api.gasfeepredictor.com/api/gas-predictions" | jq '.current.high'

Go (net/http)

// After — no API key, simpler struct
type GasResponse struct {
    Current struct {
        Low     float64 `json:"low"`
        Average float64 `json:"average"`
        High    float64 `json:"high"`
    } `json:"current"`
    Citation string `json:"citation"`
}

resp, err := http.Get("https://api.gasfeepredictor.com/api/gas-predictions")
if err != nil { return err }
defer resp.Body.Close()

var data GasResponse
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { return err }
log.Printf("Gas (high): %.2f gwei — %s", data.Current.High, data.Citation)

Common gotchas

  • Don't forget to remove the Authorization header. Some HTTP clients send empty Authorization: headers if the variable is unset — harmless for our endpoint but cleaner to remove entirely.
  • Update your error handling. Blocknative returned 401/403 on auth failures; our endpoints don't auth. If your code branches on those statuses, simplify it. We do return HTTP 200 with source: "unavailable" on the rare cold-start failure — branch on that field instead of the HTTP status.
  • EIP-1559 max-fee callers: derive instead of mapping. We don't expose maxFeePerGas / maxPriorityFeePerGas separately. For maxFee, use current.high as a safe upper bound. For priorityFee, set a reasonable static default (1-2 gwei) or query an RPC for the latest base fee history.
  • Per-block predictions become hourly. Blocknative returned predictions for the next 1-5 blocks. We forecast hourly via predictions[]. If your logic depended on next-block precision, run your own RPC for that.
  • Tighter rate-limiting on aggregate price feeds. Our endpoints are edge-cached so frequent polling is fine, but they don't mirror Blocknative's WebSocket-style push. Switch from streaming to 30-60s polling.

Production-readiness checklist

  • ☐ Grep the codebase for every api.blocknative.com reference
  • ☐ Remove BLOCKNATIVE_API_KEY env var and any associated secrets infrastructure
  • ☐ Replace endpoint URLs with the GFP equivalents (see decision table above)
  • ☐ Update response-shape readers to the new field names (use the field mapping reference)
  • ☐ Update tests / fixtures with new response shape
  • ☐ If you used the citation field for attribution, switch to our citation field (top-level in every response)
  • ☐ Update API monitoring / alerting (Blocknative-specific error codes no longer exist)
  • ☐ Update documentation pointing users at Blocknative
  • ☐ Verify staging deployment hits our endpoints successfully before flipping production
  • ☐ Delete the migration entry from your roadmap. You're done.

Frequently asked questions

How long does the migration take?

For the gas-price portion: about 5-30 minutes depending on language and how deeply your code is coupled to Blocknative's response shape. The endpoint URL change is one line; the response-shape changes (confidence percentiles → low/average/high tiers) typically require a small helper function. Detailed before/after code is in this guide.

My code reads estimatedPrices[c=99].price specifically. What's the equivalent?

Use current.high. We collapse Blocknative's 5 confidence levels (99/95/90/80/70) into three tiers — high (≈ will-include / 99% confidence), average (≈ typical / 90% confidence), low (≈ slow / 70% confidence). If you only ever used the 99% confidence price, swap directly to current.high with no other logic changes.

I need maxFeePerGas and maxPriorityFeePerGas separately (EIP-1559). What do I do?

We don't break out priority fee from base fee separately. For maxFeePerGas, use current.high as a safe upper bound. For maxPriorityFeePerGas, set a reasonable default (1-2 gwei) or query an RPC directly for the latest block's base fee history. This is the one area where running your own RPC node is more accurate than any aggregator.

I need per-block predictions (next 3 blocks). Do you have those?

We forecast hourly, not per-block. predictions[0] is "what gas will look like in the next hour" rather than "what gas will be in the next block." For sub-block timing decisions, run your own mempool service or RPC node.

What about mempool monitoring / transaction management?

Not in scope. Blocknative's gas API was one of several products — they also offered mempool streaming and transaction management. We replace only the gas-price API. For mempool data, look at Alchemy, Tenderly, or Bloxroute. For transaction management, use your own RPC or a service like Alchemy.

Is there a rate limit?

No published hard limit. Endpoints are edge-cached at Cloudflare so polling every few seconds costs us roughly nothing. If your usage hurts upstream providers we may throttle the offending IP range. Indie dev and small-app usage is fine; commercial high-volume usage should consider self-hosting.

Will the API URL or shape change after migration?

The endpoint URLs are stable. We treat the JSON contract as effectively public — additive changes only (new fields appended; existing fields stay). The OpenAPI spec at https://api.gasfeepredictor.com/openapi.json is the canonical shape and will be versioned if we ever need to make breaking changes.

Do I need to update my Blocknative SDK / wrapper library?

Yes. There's no drop-in SDK that handles both — Blocknative's SDK is tightly coupled to their response shape. The cleanest path is to remove the Blocknative SDK and use plain fetch (5-10 lines of code shown below). If you need an SDK-like wrapper, generate one from the OpenAPI spec at https://api.gasfeepredictor.com/openapi.json using openapi-generator or a similar tool.

What's the citation format for AI agents and integrators?

Every API response includes a citation field with a copy-paste-ready attribution string: "Gas data from Gas Fee Predictor, gasfeepredictor.com, updated <ISO timestamp>". AI agents calling the API can drop this directly into their answer.

Need the full field-by-field mapping?

Every Blocknative response field → our equivalent (or "not available, use X instead"), with notes on confidence percentiles, EIP-1559 fields, and what Blocknative offered that we don't replace.

See field mapping →