Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.zerion.io/llms.txt

Use this file to discover all available pages before exploring further.

Dune is sunsetting the SIM API. If you’ve been calling SIM’s endpoints for token balances, wallet activity, or DeFi positions, the same data is available on Zerion API across 60+ EVM chains and Solana, often in a single call. This guide shows the direct mapping for the main SIM endpoints, with copy-pasteable code for each. What you get with Zerion:
  • One call for wallet + DeFi: Collapse two SIM requests (balances + defi/positions) into a single /positions/?filter[positions]=no_filter response.
  • Portfolio in one shot: Total value, 24h change, and chain breakdown without computing from balances.
  • Solana on the same endpoints: Pass any EVM or Solana address to /wallets/{address}/... and get back the same enriched shape.
Zerion is offering special pricing for SIM customers during the wind-down. The discount code is in Dune’s wind-down communications, or email api@zerion.io and mention your SIM account.

Endpoint parity

Use caseDune SIMZerion API
Tokens + DeFi (one call)Two requests (balances + defi/positions)GET /v1/wallets/{address}/positions/?filter[positions]=no_filter
Portfolio total + 24h changeCompute client-side from balancesGET /v1/wallets/{address}/portfolio
Token balancesGET /v1/evm/balances/{address}GET /v1/wallets/{address}/positions/?filter[positions]=only_simple
DeFi positionsGET /v1/evm/defi/positions/{address}GET /v1/wallets/{address}/positions/?filter[positions]=only_complex
Wallet activity / transactionsGET /v1/evm/activity/{address}GET /v1/wallets/{address}/transactions/
NFTsGET /v1/evm/collectibles/{address}GET /v1/wallets/{address}/nft-positions/
Realtime updatesSubscriptions API (webhooks)Transaction webhooks
Prefer not to write code? The Zerion CLI wraps the same endpoints with a one-shot npx @zerion/cli init flow, useful for quick experiments and AI agents.

Token balances

SIM returns a flat balances[] array. Zerion returns a JSON:API collection where each token is one entry under data[], with attributes.fungible_info for metadata and attributes.value for the USD value. The same endpoint accepts both EVM and Solana addresses.
const API_KEY = process.env.ZERION_API_KEY;
const address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";

const res = await fetch(
  `https://api.zerion.io/v1/wallets/${address}/positions/?currency=usd&filter[positions]=only_simple&filter[trash]=only_non_trash&sort=-value`,
  {
    headers: {
      accept: "application/json",
      authorization: `Basic ${btoa(API_KEY + ":")}`,
    },
  }
);
const { data } = await res.json();

for (const pos of data) {
  const { fungible_info, quantity, price, value } = pos.attributes;
  const chain = pos.relationships.chain.data.id;
  console.log(`${fungible_info.symbol} on ${chain}: ${quantity.float} @ $${price} = $${value?.toFixed(2) ?? "N/A"}`);
}

Field mapping

Dune SIM (balances[].…)Zerion (data[].attributes.…)
symbol, decimals (always); name (for ERC20s, not native)fungible_info.symbol, fungible_info.name, fungible_info.implementations[].decimals (all returned by default)
address ("native" for gas tokens)fungible_info.implementations[].address (null for native)
chain / chain_idrelationships.chain.data.id (string IDs, e.g. "ethereum")
amount (raw integer string)quantity.int (1:1, raw integer string). Also exposed as quantity.float (decimal number) and quantity.numeric (decimal string) if you want pre-formatted values.
price_usdprice
value_usdvalue
token_metadata.logo (requires ?metadata=logo)fungible_info.icon.url (returned by default)
exclude_spam_tokens=true (request param)filter[trash]=only_non_trash (request param)
low_liquidity (per-token flag)No direct equivalent. Zerion exposes fungible_info.flags.verified and the wider spam classifier behind filter[trash]; filter client-side on price/value thresholds if you need a hard liquidity gate.
historical_pricesUse /v1/fungibles/{id}/charts/{period} instead
Want stablecoins only? SIM exposes asset_class=stablecoin. Zerion doesn’t ship a one-shot stablecoin filter. You have to pass filter[fungible_ids]=<id1>,<id2>,… where each value is a Zerion-specific fungible ID (not a symbol like USDC and not a contract address). Look up the IDs once via /v1/fungibles?filter[search_query]=usdc; the id on each result is what goes into filter[fungible_ids]. Cache the list of IDs for the stablecoins you care about and reuse it across requests.

Wallet activity (transactions)

SIM’s /v1/evm/activity/{address} returns chronologically-ordered, decoded transactions (sends, swaps, approvals, and so on). The direct Zerion equivalent is /v1/wallets/{address}/transactions/, which returns enriched, human-readable transactions with transfers, fees, and the dApp (when Zerion recognizes it). The same endpoint accepts both EVM and Solana addresses.
const API_KEY = process.env.ZERION_API_KEY;
const address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";
const headers = {
  accept: "application/json",
  authorization: `Basic ${btoa(API_KEY + ":")}`,
};

const res = await fetch(
  `https://api.zerion.io/v1/wallets/${address}/transactions/?currency=usd&page[size]=20`,
  { headers }
);
const { data } = await res.json();

for (const tx of data) {
  const { operation_type, mined_at, transfers, fee } = tx.attributes;
  const chain = tx.relationships.chain.data.id;
  const dappId = tx.relationships.dapp?.data?.id;

  console.log(`[${mined_at}] ${operation_type} on ${chain}`);
  if (dappId) console.log(`  via ${dappId}`);
  for (const t of transfers) {
    const sign = t.direction === "out" ? "-" : "+";
    const symbol = t.fungible_info?.symbol ?? "NFT";
    console.log(`  ${sign}${t.quantity.float} ${symbol} ($${t.value?.toFixed(2) ?? "?"})`);
  }
  console.log(`  Fee: $${fee.value?.toFixed(2) ?? "?"}`);
}

Field mapping

Dune SIM (activity[].…)Zerion (data[].attributes.…)
tx_hashhash
block_timemined_at (ISO 8601) / mined_at_block
chain_id (numeric)relationships.chain.data.id (string)
type (send, receive, swap, approve, …)operation_type (send, receive, trade, approve, deposit, withdraw, mint, burn, claim, execute, deploy)
asset_type (native, erc20, erc721, erc1155)transfers[].fungible_info vs transfers[].nft_info
tx_from / tx_to (transaction signer / recipient)sent_from / sent_to
from / to (per-asset-event party)transfers[].sender / transfers[].recipient
value (raw integer string), value_usdtransfers[].quantity.int (raw integer string, 1:1), transfers[].value (USD). .float and .numeric are decimal forms if you need them.
token_metadata.symbol, .decimals, .price_usdtransfers[].fungible_info.symbol, .implementations[].decimals, .price
(no SIM equivalent)relationships.dapp.data.id (dApp slug, e.g. "uniswap-v3", "aave-v3", present when Zerion identifies the dApp)
(no SIM equivalent)acts[].application_metadata.method.name (decoded method name, e.g. "Multicall")
(no SIM equivalent)fee.value, fee.fungible_info

Filter mapping

Dune SIM paramZerion equivalent
activity_type=swap,sendfilter[operation_types]=trade,send
asset_type=erc20filter[asset_types]=fungible
chain_ids=1,8453filter[chain_ids]=ethereum,base
token_address=0xa0b8… (contract address)filter[fungible_ids]=<zerion-fungible-id>. Zerion uses its own fungible IDs, not contract addresses. Look one up via /v1/fungibles?filter[search_query]=… or /v1/fungibles/{chain_id}:{address}.
limit=100page[size]=100
offset=<cursor>Follow links.next from the response

DeFi positions

SIM’s /v1/evm/defi/positions/{address} returns lending, staking, and LP positions. The Zerion equivalent reuses the /positions/ endpoint with filter[positions]=only_complex to return DeFi positions only. EVM only today; Solana DeFi positions are on the roadmap.
const API_KEY = process.env.ZERION_API_KEY;
const address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";

const res = await fetch(
  `https://api.zerion.io/v1/wallets/${address}/positions/?currency=usd&filter[positions]=only_complex&sort=-value`,
  { headers: { accept: "application/json", authorization: `Basic ${btoa(API_KEY + ":")}` } }
);
const { data } = await res.json();

for (const pos of data) {
  const { name, protocol, protocol_module, position_type, quantity, value } = pos.attributes;
  const chain = pos.relationships.chain.data.id;
  console.log(`[${position_type}] ${name} | ${protocol} (${protocol_module}) on ${chain}: ${quantity.float} = $${value?.toFixed(2) ?? "N/A"}`);
}

Field mapping

Dune SIM (positions[].…)Zerion (data[].attributes.…)
protocolprotocol
type (Erc4626, Aave, …)protocol_module (lending, staked, liquidity_pool, locked, rewards, vesting, deposit, investment, yield) + position_type (deposit, staked, reward, locked)
token / underlying_tokenfungible_info
balancequantity.float
price_usd, value_usdprice, value
chain / chain_idrelationships.chain.data.id
aggregations.total_value_usd/wallets/{address}/portfoliodata.attributes.total.positions
aggregations.total_by_chain/wallets/{address}/portfoliodata.attributes.positions_distribution_by_chain
(no SIM equivalent)application_metadata.name / application_metadata.icon.url (protocol display name + logo)
(no SIM equivalent)relationships.dapp.data.id to look up the dApp via /v1/dapps/{id}

Pagination

Replace SIM’s offset cursor with Zerion’s links.next URL. Each Zerion response includes a fully-formed next-page link you can fetch as-is.
async function getAll(url) {
  const all = [];
  const headers = { accept: "application/json", authorization: `Basic ${btoa(API_KEY + ":")}` };

  while (url) {
    const res = await fetch(url, { headers });
    const { data, links } = await res.json();
    all.push(...data);
    url = links?.next ?? null;
  }
  return all;
}

Webhooks (real-time updates)

SIM’s Subscriptions API pushes balance/activity events to a callback URL. Zerion offers transaction webhooks: subscribe a callback URL to one or more wallets and receive a POST when any of them transact. See the wallet activity alerts recipe for a working example.

Differences from SIM

Most SIM use cases have a direct Zerion equivalent. A few aren’t covered yet, and others behave differently. Worth a scan before you cut over. Not supported today:
  • Token holders: SIM ranks ERC20 holders by balance via /v1/evm/token-holders. Not on Zerion today; pair with a separate data source if you need holder rankings.
  • Raw RPC-style transactions: SIM’s /v1/evm/transactions returns raw block data (gas, calldata, logs). Zerion’s /transactions/ is enriched and decoded, not raw. For raw fields, use mined_at_block + hash from Zerion to look the transaction up via a node provider (Alchemy, Infura).
  • Eclipse chain: Zerion supports Solana but not Eclipse SVM. Check the supported chains list before migrating Eclipse-dependent code.
  • SVM-specific token-mint fields: SIM’s /beta/svm/balances/ returns Solana-specific fields like program_id (SPL token program), total_supply, and uri (token metadata URI). Zerion abstracts these away. Query a Solana RPC directly if you depend on them.
If any of these matter for your migration, let us know. Your feedback helps shape our roadmap. Worth knowing:
  • Authentication: SIM uses an X-Sim-Api-Key header. Zerion uses HTTP Basic Auth. Get a key at dashboard.zerion.io.
  • Chain IDs: SIM filters chains via numeric chain_ids (e.g. 1,8453). Zerion uses string chain IDs (e.g. ethereum,base). See the full list.
  • Solana: SIM splits EVM and Solana into separate endpoint families (Solana lives at /beta/svm/... with a different schema) and only exposes raw RPC-style Solana transactions, no enriched activity. Zerion accepts Solana addresses on the same /wallets/{address}/... endpoints used for EVM, and returns the same enriched activity shape (operation_type, transfers[], fee) for both chains. DeFi positions are not yet supported for Solana.
  • Pagination: SIM returns next_offset; Zerion returns a fully-formed links.next URL you can fetch as-is. See pagination.
  • Response shape: Zerion uses JSON:API. Payloads live under data[].attributes with related entities under data[].relationships.
  • Spam filtering: SIM has exclude_spam_tokens; Zerion uses filter[trash]=only_non_trash. See spam filtering for the full taxonomy.
  • One endpoint for wallet and DeFi: Zerion serves both wallet tokens and DeFi positions from /positions/. Switch via filter[positions]=only_simple (wallet only) or only_complex (DeFi only).
  • Stablecoin filter: SIM has asset_class=stablecoin. Zerion requires a comma-separated filter[fungible_ids]=… list. See the stablecoins note above.
  • Supply / borrow split: Some SIM DeFi positions split a single lending position into separate supply and borrow rows. Zerion returns one row per position with position_type and the underlying token; reconstruct directions from quantity sign or position_type semantics.
  • LP tick ranges and VeNFT lock metadata: SIM exposes raw LP tick ranges and vote-escrow lock dates. Zerion abstracts these away and surfaces the position’s USD value, underlying token, and protocol module.
  • Pool size / low liquidity flags: SIM provides per-token pool_size and low_liquidity flags. Zerion’s spam classifier filters dust via filter[trash], but does not expose a numeric pool size.

Get in touch

Have a use case we don’t cover or need assistance with the migration? Our team is happy to help! Reach out via the chat widget on dashboard.zerion.io, or email us.