base-gas-x402

Gas data for agents on Base. Five endpoints, no API key, paid per call in USDC.

Including the one answer nobody else gives you: sometimes there is nothing to optimise.

Sampling Base gas every 5 minutes, 168 hours of retention. Check /health

What this is

A pay-per-call gas oracle for Base mainnet that AI agents can use without an API key, a signup, or a subscription. Payment settles in USDC on Base (eip155:8453) through the Coinbase CDP production facilitator.

Who it is for

Developers building AI agents that transact on Base. And, secondarily, developers evaluating x402 as a way to sell their own APIs: all of it is open source and readable as a reference implementation.

Why not just call an RPC?

An RPC tells you the current gas price but not whether it is high or low, because it has no memory. This service samples Base every five minutes, so it can answer:

  • Is gas cheap, normal, expensive, or flat right now?
  • How does Base compare to OP Mainnet, Arbitrum One, and Ethereum?
  • Would waiting for a cheaper hour actually help?

The 402 part

HTTP 402 Payment Required has been reserved and unused since 1997. x402 finally uses it. Your agent requests data, the server answers 402 with a price, the agent pays in USDC, and the data comes back. One round trip, no account.

See it for yourself. This costs nothing, you never pay the challenge itself:

the 402 challenge
curl -i https://base-gas-x402-production.up.railway.app/gas

Setup

Three ways in. Pick one.

1. Agent skill (recommended)

install
npx skills add memosr/base-gas-skill --all --yes

Then ask the agent: What is gas on Base right now?

The paid routes need a funded AgentCash wallet:

wallet
npx agentcash@latest onboard
npx agentcash@latest balance

2. MCP server

install
npx agentcash@latest install -y
npx skills add memosr/base-gas-skill/mcp --all --yes

Published on npm as base-gas-mcp.

3. Direct HTTP

free, no wallet needed
curl -s https://base-gas-x402-production.up.railway.app/health
paid
npx agentcash@latest fetch "https://base-gas-x402-production.up.railway.app/gas?gasLimit=180000"

Full docs live with the code: API repo, skill repo, OpenAPI.

Five routes

Prices are transcribed from /openapi.json, which is the source of truth.
RoutePriceReturns
GET /gas$0.005Base fee, priority tiers, gas price, cost for any gasLimit
GET /gas/compare$0.01Base, OP Mainnet, Arbitrum One, Ethereum, cheapest first
GET /gas/history$0.012Time series, min/max/avg/median, verdict, spreadPercent
GET /gas/cheapest-window$0.02hasDailyCycle, recommendation, hourly averages
GET /healthfreeSamples, hours covered, interval, retention

/gas and /gas/compare take gasLimit (21000 to 30000000). /gas/history and /gas/cheapest-window take hours (1 to 168).

Pass the gas limit of the operation and get its actual cost.
OperationgasLimit
ETH transfer21000
ERC-20 transfer65000
NFT mint85000
Uniswap swap180000
Contract deploy1500000

Real response: /gas/compare

Base comes second here, not first. That is left in on purpose: anyone can call the endpoint and check.

GET /gas/compare
{
  "gasLimit": 21000,
  "chains": [
    { "chain": "optimism", "label": "OP Mainnet", "gasPrice": "0.001000371",
      "estimatedCost": { "eth": "0.000000021007791" } },
    { "chain": "base", "label": "Base", "gasPrice": "0.006",
      "estimatedCost": { "eth": "0.000000126" } },
    { "chain": "arbitrum", "label": "Arbitrum One", "gasPrice": "0.02",
      "estimatedCost": { "eth": "0.00000042" } },
    { "chain": "ethereum", "label": "Ethereum", "gasPrice": "0.046909277",
      "estimatedCost": { "eth": "0.000000985094817" } }
  ],
  "cheapest": "optimism",
  "baseRank": 2,
  "baseVsEthereum": "Base is 7.8x cheaper than Ethereum",
  "unavailable": []
}

Real response: /gas/cheapest-window

GET /gas/cheapest-window
{
  "hasDailyCycle": false,
  "recommendation": "No meaningful daily gas cycle on this chain: the gap between the cheapest and priciest hour is 0%. Timing a transaction by hour of day will not save anything. Transact whenever you need to.",
  "savingsPercent": 0
}

This is the answer you will usually get on Base. Measured across two independent 15-hour windows, the gap between the cheapest and priciest hour was effectively zero.

Advantages and differences

Several Base gas endpoints exist, including multi-chain toolkits covering seven chains to this one's one. Here is where this one differs.

Focused, not a dumping ground
Five routes, one question each. Competitors ship 67, 307, and 353 endpoints; the AgentCash validator warns above 40, because a large surface eats an agent's token budget.
Honest about its own data
/health is free and reports how much history exists, so you can decide whether a paid history call is worth it. Every paid response carries a coverage object. No competitor does this.
It tells you when there is nothing to do
On the fee floor, /gas/history returns flat and /gas/cheapest-window returns hasDailyCycle: false. An endpoint that always names a "cheapest hour" is selling a decision that cannot be made.
Priced per operation
Pass gasLimit, get the cost of the thing you are about to do, not a gwei figure to multiply yourself.
Fails partially, not totally
/gas/compare reads four chains independently. One dead RPC lands in unavailable instead of killing the response you paid for.
Open source, end to end
API, MCP server, and skill are public and MIT licensed. The skill ships rules that steer agents away from overspending.
Cheapest current-gas endpoint in the category
/gas at $0.005, against $0.01, $0.013, $0.05, and $0.10. Only for /gas: /gas/history at $0.012 is not the cheapest, a $0.001 competitor exists.

What it is not: not the only or first Base gas API, and not the cheapest overall. It will not save you money by timing transactions on Base, because there is nothing there to time. Single instance on Railway, no uptime guarantee and no SLA. No usage numbers to quote, it is new.

Findings

Two x402 failure modes found while building this. Both are reproducible and both cost hours. If you run an x402 origin, they may save you an afternoon.

1. A missing trust proxy silently blocks discovery

Railway and most PaaS edges terminate TLS and forward plain HTTP. Express reports req.protocol as http, x402 advertises an http:// resource, and Bazaar registration fails hourly with:

hourly, invisibly
resource must start with 'https://' when protocol type is http

Nothing surfaces it: the discovery CLI reports zero warnings and the endpoints stay live and payable, while the index never updates. One line fixes it:

the fix
app.set("trust proxy", true);

2. The CDP facilitator size-limits the payment payload

The bazaar metadata from the 402 challenge is echoed back inside the payment payload. Past a threshold the facilitator reports it as a schema error:

not actually a schema problem
'paymentPayload' is invalid: must match one of [x402V2Pay...

Measured on Base, same wallet and client: 4188 bytes accepted, 4260 bytes rejected. One endpoint stopped accepting payment purely because its description was longer than the others. Writing better documentation made it unpayable.