Skip to main content
If you’ve been calling the Moralis Web3 Data API for wallet balances, net worth, transaction history, PnL, DeFi positions, or token prices, the same data is available on Zerion API across 60+ EVM chains and Solana, usually in a single call. This guide shows the direct mapping for the main Moralis wallet endpoints, with copy-pasteable code for each. What you get with Zerion:
  • One address, all chains: Most Moralis endpoints take a single chain parameter per call, so a multi-chain read means one request per chain. Zerion returns every supported chain for an address in one call, filterable with filter[chain_ids].
  • One API for EVM and Solana: Moralis serves Solana from a separate base URL (solana-gateway.moralis.io) with a different response schema. Zerion accepts Solana addresses on the same /wallets/{address}/... endpoints used for EVM.
  • One call for tokens + DeFi: Moralis splits wallet tokens (/wallets/{address}/tokens) and DeFi positions (a separate API) into different products. Zerion serves both from /positions/?filter[positions]=no_filter.

Endpoint parity

Moralis paths below are relative to https://deep-index.moralis.io/api/v2.2 unless noted.
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.

A note on chains

The biggest structural change is how you address chains:
  • Moralis: Most endpoints take one chain query parameter per call (chain=eth, chain=0x1), so covering a wallet across five chains means five requests. Only net worth (and the newer Universal API endpoints) accept multiple chains at once.
  • Zerion: GET /v1/wallets/{address}/... returns every supported chain for the address by default, narrowed with filter[chain_ids]=ethereum,base. Chain IDs are full lowercase names (ethereum, not eth or 0x1); see the full list.
So a per-chain fan-out loop over chain=eth, chain=polygon, chain=base becomes a single Zerion call, with the chain of each row in relationships.chain.data.id.

Token balances

Moralis’s /wallets/{address}/tokens returns result[] with balance (raw integer), balance_formatted, usd_price, and usd_value per token, for one chain per call. Zerion returns a JSON:API collection covering all chains at once, with attributes.fungible_info for metadata, attributes.quantity for amounts, and attributes.value for USD values. The same endpoint accepts both EVM and Solana addresses.

Field mapping

price and value are null for tokens without a reliable price. Guard for null before summing or formatting.
If you’re on the legacy GET /{address}/erc20 + GET /{address}/balance pair, the same /positions/ call replaces both: native tokens come back as regular rows (implementation address: null), already decimal-adjusted and priced.

Net worth

Moralis’s net-worth returns total_networth_usd with a per-chain breakdown of native vs token value. Zerion’s /portfolio returns the total, the 24h change, a breakdown by chain, and a breakdown by position type (wallet, deposited, borrowed, locked, staked) in one response.

Field mapping

Wallet history

Moralis’s /wallets/{address}/history returns decoded transactions for one chain per call, with a category label, a summary sentence, and transfers split into erc20_transfers[], native_transfers[], and nft_transfers[]. Zerion’s /transactions/ returns enriched transactions across all chains at once, with a single decoded operation_type, one unified transfers[] array, fees, and the dApp when Zerion recognizes it. The same endpoint accepts both EVM and Solana addresses.

Field mapping

Filter mapping

Wallet PnL

Moralis’s profitability endpoints return realized PnL only, per token (/profitability) or as totals (/profitability/summary), for one chain per call. Zerion’s /pnl returns wallet-level PnL computed with FIFO across all chains: realized and unrealized gain, net invested, total fees, and external in/out flows.

Field mapping

See the wallet PnL tracker recipe for a worked example including per-token filtering.

DeFi positions

Moralis serves DeFi positions from its newer Universal API (api.moralis.com/v1), where each position nests a tokens[] array typed as supplied, borrowed, reward, or lp. Zerion flattens this: each position is one row under /positions/?filter[positions]=only_complex, tagged with protocol, protocol_module, and position_type (including loan for borrowed assets).

Field mapping

Moralis returns positions labeled perps. Zerion’s positions model is spot and DeFi-protocol oriented and does not return perpetuals as positions. If perps matter for your migration, let us know.

Token prices

Moralis’s /erc20/{address}/price returns a DEX-pair-derived price with exchange metadata, one token and one chain per call. Zerion resolves a token by its implementation and returns full asset metadata including market_data.price and recent changes.

Field mapping

If you also call GET /erc20/metadata, the same fungible objects carry the metadata: market_data.total_supply, market_data.circulating_supply, market_data.market_cap, and market_data.fully_diluted_valuation map to Moralis’s total_supply, circulating_supply, market_cap, and fully_diluted_valuation.

NFTs

Moralis’s GET /{address}/nft returns raw NFT holdings with tokenURI-based metadata for one chain per call. The Zerion equivalent is /v1/wallets/{address}/nft-positions/, which returns each holding with collection metadata and floor-price-based valuation across chains.
cURL

Solana

Moralis serves Solana from a separate API (https://solana-gateway.moralis.io) with camelCase responses that don’t match the EVM schema. On Zerion, Solana addresses go through the same wallet endpoints as EVM and return the same shape: Transaction history for Solana addresses works on the same /transactions/ endpoint. DeFi positions are not yet supported for Solana.

Pagination

Replace Moralis’s cursor query parameter with Zerion’s links.next URL. Each Zerion response includes a fully-formed next-page link you can fetch as-is.

Realtime updates

Moralis Streams pushes on-chain events to your backend via webhooks. Zerion’s equivalent is 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 Moralis

Most Moralis wallet use cases have a direct Zerion equivalent. A few aren’t covered, and others behave differently. Worth a scan before you cut over. Not supported today:
  • Price at a block and DEX-pair detail: Moralis prices accept to_block and return the source exchange, pair address, and pair liquidity. Zerion returns an aggregated live price plus a chart timeseries.
  • Per-token trade analytics: Moralis’s per-token PnL rows include average buy/sell prices and trade counts, and /swaps classifies each swap as a buy or sell. Zerion’s PnL is wallet-level (scopeable per token with filter[fungible_ids]), and trades are operation_type: trade transactions you classify from transfer directions.
  • Address labels: Moralis annotates transactions with from_address_label / to_address_label (exchanges, known entities). Zerion identifies dApps (relationships.dapp) but does not label counterparty addresses.
  • Token analytics signals: securityScore, pair liquidity, and holder data have no Zerion equivalent. Use filter[trash] and fungible_info.flags.verified for curation.
  • Perpetuals: Moralis DeFi positions include a perps label. Zerion does not return perpetuals as positions.
  • Bitcoin: Moralis Streams can watch Bitcoin addresses. Zerion covers EVM chains and Solana; check the supported chains list for the ones you rely on.
If any of these matter for your migration, let us know. Your feedback helps shape our roadmap. Worth knowing:
  • Authentication: Moralis uses an X-API-Key header. Zerion uses HTTP Basic Auth. Get a key at dashboard.zerion.io.
  • Chains: Moralis takes one chain per call (eth, 0x1). Zerion returns all supported chains by default and filters with full names: filter[chain_ids]=ethereum,base. See the note above.
  • One base URL: Moralis splits EVM (deep-index.moralis.io), Solana (solana-gateway.moralis.io), and the Universal API (api.moralis.com) across different hosts and schemas. Zerion serves everything from api.zerion.io/v1 with one response shape.
  • Consistent casing: Moralis mixes snake_case (wallet endpoints) and camelCase (prices, swaps, Solana, Universal API) across endpoint families. Zerion responses are uniformly snake_case JSON:API: payloads live under data[].attributes with related entities under data[].relationships.
  • One endpoint for tokens and DeFi: Zerion serves both wallet tokens and DeFi positions from /positions/. Switch via filter[positions]=only_simple (wallet only), only_complex (DeFi only), or no_filter (both).
  • Flattened DeFi: Moralis nests typed tokens[] inside each position. Zerion returns one row per position leg tagged with protocol_module and position_type (including loan for debt). Group by relationships.dapp.data.id to reconstruct protocols, and by group_id to reconstruct LP pairs.
  • USD values in history: Moralis history returns transfer amounts without USD values. Zerion returns value (USD at execution time) on each transfer and fee.
  • Wallet value over time: Moralis has no net-worth-history endpoint. Zerion’s /charts/{period} returns the wallet’s value timeseries directly.
  • Spam filtering: Moralis flags possible_spam and gates with exclude_spam / liquidity thresholds. Zerion uses filter[trash]=only_non_trash. See spam filtering.
  • Pagination: Moralis pages with a cursor parameter; Zerion returns a fully-formed links.next URL you can fetch as-is. See pagination.

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.