Phantrium Chainchain infrastructure

Docs

Point your client at us and keep going.

Standard JSON-RPC over HTTPS. If your code already talks to a node, the only thing that changes is the URL.

Quickstart

Create an account, make a key, send a request. Nothing else to install.

curl

curl https://rpc.phantrium.com/v1/ethereum/YOUR_KEY \
  -X POST \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

viem

import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'

const client = createPublicClient({
  chain: mainnet,
  transport: http('https://rpc.phantrium.com/v1/ethereum/YOUR_KEY')
})

const block = await client.getBlockNumber()

ethers

import { JsonRpcProvider } from 'ethers'

const provider = new JsonRpcProvider(
  'https://rpc.phantrium.com/v1/base/YOUR_KEY'
)

Prefer to keep the key out of the URL? Send it as a header instead: Authorization: Bearer YOUR_KEY against https://rpc.phantrium.com/v1/ethereum. Use the header in production. A key in the path travels through every proxy, browser history and log between you and us. We strip it from our own access logs, but we are not the only hop, and we would rather tell you that than let the shorter example look free of consequence.

Endpoints

One URL shape for every chain: https://rpc.phantrium.com/v1/<chain>/<key>

ChainSlugChain IDType
Ethereumethereum0x1 · 1L1
Polygon PoSpolygon0x89 · 137L1
Basebase0x2105 · 8453L2
Arbitrum Onearbitrum0xa4b1 · 42161L2

Batch requests are supported — send an array, get an array back, up to 50 calls per batch. Each call in the batch is metered separately, because each one costs us separately.

Keys

Shown once

A key is displayed at creation and never again — we store only a hash. Lost it? Revoke and make a new one; that takes five seconds and is safer than a system that can show you your own secret.

Scope it

Restrict a key to your domains or IP addresses from the dashboard. A key that only works from your own backend is worth much less to whoever finds it in a bundle.

Revoking takes effect within 30 seconds everywhere — that is the lifetime of our key cache, and we would rather tell you the number than let you guess it.

Weighted units

We bill units, not requests. An eth_getLogs over 200,000 blocks is not the same work as an eth_chainId, and pricing that pretends otherwise ends in an invoice nobody can explain.

UnitsMethodsWhy
1eth_chainId, eth_blockNumber, eth_gasPrice, net_version, web3_clientVersionAnswered from memory
2eth_getBalance, eth_getCode, eth_getStorageAt, eth_getTransactionCount, eth_getBlockByNumber, eth_getTransactionByHash, eth_getTransactionReceiptOne state lookup
3eth_feeHistoryReads a window of blocks
4eth_call, eth_sendRawTransactionExecutes or broadcasts
6eth_estimateGas, eth_createAccessListExecutes repeatedly to find a bound
10 + rangeeth_getLogs, eth_getFilterLogs+5 units per 1,000 blocks scanned, capped at +500
60–100debug_trace*, trace_*Replays execution; by far the most expensive thing you can ask a node
4anything not listedDefault weight

Every response carries X-Chain-Units for that call and X-Chain-Quota-Remaining for the month, so you can meter yourself without waiting for an invoice.

Methods that touch node-local accounts or administration — eth_accounts, eth_sign, personal_*, miner_*, admin_* — are refused, not proxied. A shared endpoint has no accounts to unlock.

Limits

Two separate limits: how fast you may ask, and how much you may use in a month.

PlanUnits / monthRequests / secondActive keysPrice
Beta1,000,00053free
Starter25,000,0002510€29 / month
Growth150,000,00010030€99 / month
Scale600,000,000300100€299 / month

We stop instead of billing you

At 100% of your monthly units the gateway returns HTTP 429 with the numbers in the body. There is no overage rate, because an invoice you did not agree to is not a business model.

You get an email at 80%. Move up a plan and the limit lifts immediately — no waiting for a sales call.

Verified answers

On Ethereum your call is answered by a node we run ourselves, and the answer is checked before you get it. X-Chain-Verified tells you whether that happened.

Header valueWhat it means
yesOur own Helios light client produced this answer and checked it against a chain header it verified itself through the beacon sync committee.
noA vetted upstream answered. Either the chain has no Phantrium node yet (Polygon, Base, Arbitrum), or the method is one our light client does not implement, or our node was out of rotation at that moment.
partialA batch in which some calls were verified and others were not.

Methods our light client does not implement — eth_feeHistory, debug_*, trace_* — are forwarded to an upstream and answered normally. You lose the verification, not the call. The header will never say yes for an answer we could not prove; if our node is down or lagging behind the chain head it is taken out of rotation and the header drops to no. What the node is, and is not.

Caching

Answers that cannot change any more are served from our cache. It makes your calls faster and our margin real — and X-Chain-Cache: HIT tells you when it happened. A cached answer keeps the verification status it had when it was stored, so X-Chain-Verified stays truthful on a cache hit.

MethodCached forReason
eth_chainId, net_version1 hourConstant for the life of the chain
eth_getBlockByNumber (fixed number)10 minutesA finalised block does not change
eth_getBlockByHash10 minutesAddressed by content
eth_getTransactionByHash, eth_getTransactionReceipt30 secondsShort on purpose — a reorg must not catch us
eth_blockNumber2 secondsCheaper than a stampede, fresh enough to be true
eth_call, eth_getLogs, anything with latestnot cachedThe answer depends on the head

Cached responses still count units. The cache exists to make your latency and our cost better, not to make metering ambiguous.

Errors

HTTP status for anything about your account; JSON-RPC error for anything about the chain.

StatusMeansDo
401Key missing, wrong, or revokedCheck the key in the dashboard
403Key is restricted to other domains or IPsWiden the restriction, or call from the right place
429Rate limit or monthly quota reached — the body says whichBack off, or change plan
404Unknown chain slugSee the endpoint table above
413Body over 1 MBSplit the batch
200 + JSON-RPC errorThe chain rejected the call — a revert, bad params, a missing blockThat is an answer, not an outage: it is billed and not retried

If no backend answers, you get JSON-RPC -32603 and we get an alert. Check the status page before you start debugging your own code.