Every Zerion v1 wallet endpoint, mapped to its GoldRush equivalent.
Zerion API is a wallet and portfolio API across 40+ EVM chains and Solana, returning JSON:API payloads. GoldRush is a decoded multichain data API across 100+ chains including Bitcoin, returning a flat data.items[] envelope. Most Zerion wallet reads have a direct GoldRush equivalent; DeFi protocol positions, one-call PnL, and transaction webhooks do not. This page maps all of it, including the parts where you should stay on Zerion.
The cross-cutting differences. Miss one and every call fails the same way, so fix these first.
| Zerion API | GoldRush | |
|---|---|---|
| Base URL | https://api.zerion.io | https://api.covalenthq.com |
| Auth | HTTP Basic: API key as username, empty password: Authorization: Basic base64(KEY + ':') | Authorization: Bearer <GOLDRUSH_API_KEY> |
| Chain addressing | All chains by default; narrow with filter[chain_ids]=ethereum,base. Chain per row under relationships.chain.data.id. | Chain is a path segment: eth-mainnet, base-mainnet, matic-mainnet. Use the /v1/allchains/* endpoints for cross-chain reads in one call. |
| Response envelope | JSON:API format: payload under data[].attributes, related entities under data[].relationships. Errors via HTTP status. | Flat envelope: { data: { items: [...] }, error, error_message, error_code }. Errors carry an HTTP status AND the error fields. |
| Token amounts | quantity.float (decimal), quantity.int (raw), quantity.numeric (decimal string) | balance is the raw integer string; contract_decimals is a sibling field. Divide yourself, or read the pre-computed quote for fiat value. |
| Pagination | Fully-formed next-page URL at links.next, fetched as-is. | Page number in the path: .../transactions_v3/page/{page}/. Page 0 is the OLDEST page, not the newest. |
Every Zerion API endpoint we could source, with its GoldRush equivalent. Rows marked No equivalent are gaps we won't paper over, so read those first. Verify a row against the Zerion API docs before relying on it.
| Use case | Zerion API | GoldRush | Parity |
|---|---|---|---|
| Token balancesGoldRush returns spot quote per token in the same response, so no second pricing call. | GET /v1/wallets/{address}/positions/?filter[positions]=only_simple | GET /v1/{chainName}/address/{walletAddress}/balances_v2/ | Direct equivalent |
| Multichain balances in one callPass a comma-separated chains list to narrow, the same way filter[chain_ids] narrows Zerion. | GET /v1/wallets/{address}/positions/ (all chains by default) | GET /v1/allchains/address/{walletAddress}/balances/ | Direct equivalent |
| DeFi protocol positionsNo GoldRush equivalent. LP and receipt tokens appear in balances_v2 as tokens, but not decoded per protocol. Keep Zerion if this is load-bearing. | GET /v1/wallets/{address}/positions/?filter[positions]=only_complex | None | No equivalent |
| Net worth + 24h changeSum the quote field across items. Zerion returns the total pre-computed; GoldRush makes you add it up. | GET /v1/wallets/{address}/portfolio | GET /v1/allchains/address/{walletAddress}/balances/ | Needs work |
| Net worth over timeGoldRush is per-chain; call per chain and sum for a multichain curve. | GET /v1/wallets/{address}/charts/{chart_period} | GET /v1/{chainName}/address/{walletAddress}/portfolio_v2/ | Needs work |
| Historical token balancesGoldRush returns per-token balances as of a date, not just a portfolio total. | Derived from the wallet chart endpoint | GET /v1/{chainName}/address/{walletAddress}/historical_balances/ | GoldRush advantage |
| Transaction historyZerion gives a unified transfers[] with operation_type. GoldRush gives decoded log_events per transaction: lower level, more of it. | GET /v1/wallets/{address}/transactions/ | GET /v1/{chainName}/address/{walletAddress}/transactions_v3/page/{page}/ | Direct equivalent |
| Multichain transactions | GET /v1/wallets/{address}/transactions/ (all chains by default) | GET /v1/allchains/transactions/ | Direct equivalent |
| Single transaction by hashGoldRush looks a hash up directly. Zerion requires a wallet context plus a search filter. | GET /v1/wallets/{address}/transactions/?filter[search_query]=<hash> | GET /v1/{chainName}/transaction_v2/{txHash}/ | GoldRush advantage |
| Wallet PnLNo single-call equivalent. Computable from transactions_v3 plus historical pricing, but that is your code. | GET /v1/wallets/{address}/pnl | None | No equivalent |
| NFTs held | GET /v1/wallets/{address}/nft-positions/ | GET /v1/{chainName}/address/{walletAddress}/balances_nft/ | Direct equivalent |
| NFTs by collection | GET /v1/wallets/{address}/nft-collections/ | GET /v1/{chainName}/address/{walletAddress}/collection/{collectionContract}/ | Direct equivalent |
| Token price by contractSame endpoint serves live and historical. Pass from/to for a range. | GET /v1/fungibles/by-implementation?implementation={chain}:{address} | GET /v1/pricing/historical_by_addresses_v2/{chainName}/{quoteCurrency}/{contractAddress}/ | Direct equivalent |
| Token price chartDate range instead of a named period. | GET /v1/fungibles/{fungible_id}/charts/{chart_period} | GET /v1/pricing/historical_by_addresses_v2/{chainName}/{quoteCurrency}/{contractAddress}/ | Direct equivalent |
| Pool / DEX spot price | Not available | GET /v1/pricing/spot_prices/{chainName}/pools/{contractAddress}/ | GoldRush advantage |
| Chains a wallet has usedOne call, returns the chain list directly rather than deriving it from a portfolio breakdown. | Derive from positions_distribution_by_chain on /portfolio | GET /v1/address/{walletAddress}/activity/ | GoldRush advantage |
| Supported chain listIdentical path. GoldRush adds /v1/chains/status/ for per-chain sync height and freshness. | GET /v1/chains/ | GET /v1/chains/ | Direct equivalent |
| Token approvals / risk | Not available | GET /v1/{chainName}/approvals/{walletAddress}/ | GoldRush advantage |
| Real-time updatesNo webhook product. You poll transactions_v3 or allchains/transactions. | GET/POST /v1/tx-subscriptions/ (webhooks) | None | No equivalent |
| Swap / bridge quotesGoldRush is a data API and does not quote swaps. | GET /v1/swap/quotes/ | None | No equivalent |
| Bitcoin balancesPlus /hd_wallets/ for xpub-derived addresses and /historical_balances/. | Not available (EVM + Solana only) | GET /v1/btc-mainnet/address/{walletAddress}/balances_v2/ | GoldRush advantage |
| Contract log eventsAlso by topic hash at /v1/{chainName}/events/topics/{topicHash}/. | Not available | GET /v1/{chainName}/events/address/{contractAddress}/ | GoldRush advantage |
| Token holders at a block | Not available | GET /v1/{chainName}/tokens/{tokenAddress}/token_holders_v2/ | GoldRush advantage |
Sources: developers.zerion.io and goldrush.dev for Zerion API, the GoldRush docs for GoldRush.
Code you can paste. On the left, what you have on Zerion API; on the right, the GoldRush replacement.
Zerion API
// BEFORE -- Zerion: Basic auth, JSON:API envelope, all chains by default
const auth = Buffer.from(process.env.ZERION_API_KEY + ":").toString("base64");
const res = await fetch(
"https://api.zerion.io/v1/wallets/" + address +
"/positions/?currency=usd&filter[positions]=only_simple",
{ headers: { accept: "application/json", authorization: "Basic " + auth } }
);
const { data } = await res.json();
// Amounts live under attributes; chain under relationships.
const tokens = data.map((p) => ({
symbol: p.attributes.fungible_info.symbol,
amount: p.attributes.quantity.float,
usd: p.attributes.value,
chain: p.relationships.chain.data.id,
}));GoldRush
// AFTER -- GoldRush: Bearer auth, flat items[], one chain per path
const res = await fetch(
"https://api.covalenthq.com/v1/eth-mainnet/address/" + address + "/balances_v2/",
{ headers: { Authorization: "Bearer " + process.env.GOLDRUSH_API_KEY } }
);
const { data, error, error_message } = await res.json();
if (error) throw new Error(error_message);
// balance is the raw integer string; divide by contract_decimals yourself.
const tokens = data.items.map((t) => ({
symbol: t.contract_ticker_symbol,
amount: Number(t.balance) / 10 ** t.contract_decimals,
usd: t.quote,
chain: data.chain_name,
}));Zerion API
// BEFORE -- Zerion returns every chain by default; narrow with a filter.
const res = await fetch(
"https://api.zerion.io/v1/wallets/" + address +
"/positions/?filter[chain_ids]=ethereum,base,arbitrum",
{ headers: { authorization: "Basic " + auth } }
);GoldRush
// AFTER -- GoldRush uses a dedicated allchains endpoint.
const res = await fetch(
"https://api.covalenthq.com/v1/allchains/address/" + address +
"/balances/?chains=eth-mainnet,base-mainnet,arbitrum-mainnet",
{ headers: { Authorization: "Bearer " + process.env.GOLDRUSH_API_KEY } }
);
const { data } = await res.json();Zerion API
// BEFORE -- Zerion hands you the next URL; follow it until it is absent.
let url =
"https://api.zerion.io/v1/wallets/" + address + "/transactions/?page[size]=100";
const all = [];
while (url) {
const res = await fetch(url, { headers: { authorization: "Basic " + auth } });
const body = await res.json();
all.push(...body.data);
url = body.links?.next;
}GoldRush
// AFTER -- GoldRush pages by number in the path.
// NOTE: page 0 is the OLDEST page. Walk down from has_more, or start at 0
// and ascend if you want chronological order.
const all = [];
let page = 0;
for (;;) {
const res = await fetch(
"https://api.covalenthq.com/v1/eth-mainnet/address/" + address +
"/transactions_v3/page/" + page + "/",
{ headers: { Authorization: "Bearer " + process.env.GOLDRUSH_API_KEY } }
);
const { data, error, error_message } = await res.json();
if (error) throw new Error(error_message);
all.push(...data.items);
if (!data.links?.next) break;
page += 1;
}Zerion API
# BEFORE -- Zerion requires a dashboard account and a provisioned key
# before an agent can make its first call.
curl -H "Authorization: Basic $(printf '%s:' "$ZERION_API_KEY" | base64)" \
"https://api.zerion.io/v1/wallets/$ADDRESS/positions/"GoldRush
# AFTER -- GoldRush x402: the agent pays from its own wallet.
# No signup, no dashboard, no long-lived credential to rotate.
curl "https://api.covalenthq.com/v1/eth-mainnet/address/$ADDRESS/balances_v2/"
# -> 402 Payment Required, with payment details in the response.
# An x402-aware client settles onchain and retries automatically.The port in order. Each step is small enough to ship and check on its own.
Replace HTTP Basic (key as username, empty password) with Authorization: Bearer <GOLDRUSH_API_KEY>. This is the change that breaks every call at once if you miss it.
Zerion uses plain lowercase names (ethereum, base). GoldRush uses suffixed slugs in the path (eth-mainnet, base-mainnet). Pull the authoritative list from GET /v1/chains/ rather than hardcoding a map.
Zerion returns all chains by default and narrows with filter[chain_ids]. In GoldRush, single-chain calls put the chain in the path; cross-chain calls use /v1/allchains/*. Decide per call site which one you want.
Replace JSON:API traversal (data[].attributes, data[].relationships) with the flat data.items[] envelope, and check the error and error_message fields in addition to the HTTP status.
Zerion's quantity.float is already decimal-adjusted. GoldRush returns balance as a raw integer string with contract_decimals alongside. Divide before displaying, or read quote for the fiat value.
Swap links.next URL-following for page numbers in the path. Remember that page 0 is the oldest page on transactions_v3.
DeFi protocol positions, one-call PnL, and transaction webhooks have no GoldRush equivalent. Either drop the feature, compute it from primitives, or keep Zerion alongside GoldRush for those specific reads.
Run both APIs against the same address and diff token counts and USD totals before cutting traffic over. Expect small differences from spam-token filtering policy.
If one of these is load-bearing for your product, don't migrate that surface. Running both providers is a legitimate answer.
There is no GoldRush endpoint that returns staking, lending, or LP positions decoded per protocol. balances_v2 returns LP and receipt tokens as token balances, so the value is visible, but the protocol-level breakdown is not. This is a real gap, not a naming difference.
GoldRush has no one-shot realized/unrealized PnL endpoint. You can compute it from transactions_v3 plus historical pricing, but that is your code to write, not a field to read. If PnL is the product, budget for it.
GoldRush is request/response. There is no subscription endpoint that pushes transactions to a callback URL, so any real-time path becomes polling on your side.
Each of these maps to a row above or to a documented GoldRush capability.
Live chain list at /v1/chains/ and per-chain sync state at /v1/chains/status/. Bitcoin is first-class with its own balances, historical balances, and HD-wallet endpoints. Most wallet APIs are EVM-only or EVM+Solana.
An autonomous agent can pay per request from an onchain wallet without registering an account or holding a key. If you are building agents rather than a dashboard, this removes the credential provisioning step entirely.
GoldRush serves JSON-RPC across 30+ EVM chains, so a decoded-data provider and a node provider can collapse into one vendor and one bill.
Raw and decoded log events by contract or topic, token holder lists at a block height, and pool-level pricing. Wallet-portfolio APIs generally stop at the wallet boundary and cannot answer contract-level questions.
A free API key comes with 25,000 credits and no card. Or skip signup and pay per request with x402.
This guide assumes you have decided to move. The comparison covers pricing, coverage and features side by side.
GoldRush vs Zerion APISim shut down on 1 August 2026. Here is where each endpoint goes.
Swap POST-with-key-in-URL Data APIs for flat GET endpoints.
Map the /v1/user/* Pro API onto GoldRush, including what does not port.