> ## 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.

# Migrate from GoldRush (Covalent) to Zerion API

> Migrate from GoldRush (Covalent) to Zerion API with endpoint mappings for token balances, transactions, prices, NFTs, DeFi positions, and PnL.

If you've been calling Covalent's [GoldRush API](https://goldrush.dev/docs/) (formerly the Covalent Unified API) for wallet balances, transactions, portfolio history, prices, or NFTs, the same data is available on Zerion API across [60+ EVM chains and Solana](/supported-blockchains), usually in a single call. You also get two things GoldRush doesn't offer: DeFi protocol positions and wallet PnL.

This guide shows the direct mapping for the main GoldRush endpoints, with copy-pasteable code for each.

What you get with Zerion:

* **DeFi positions and PnL:** GoldRush returns token balances and raw transactions but no DeFi protocol positions (staking, lending, LPs) and no wallet PnL. Zerion returns both, from [`/positions/`](/api-reference/wallets/get-wallet-fungible-positions) and [`/pnl`](/api-reference/wallets/get-wallet-pnl).
* **One address, all chains:** GoldRush's core endpoints take a `chainName` in the path, one chain per call. Zerion returns every supported chain for an address in one call, filterable with `filter[chain_ids]`.
* **Decoded, not raw:** GoldRush transactions return `log_events[]` you interpret yourself. Zerion returns a decoded `operation_type` and a unified `transfers[]` array with token metadata and USD values inlined.
* **Decimal-adjusted amounts:** GoldRush balances are raw integer strings you divide by `10^contract_decimals`. Zerion returns `quantity.float` alongside the raw value.

## Endpoint parity

| Use case | GoldRush API | Zerion API |
| - | - | - |
| Token balances | `GET /v1/{chainName}/address/{address}/balances_v2/` | [`GET /v1/wallets/{address}/positions/?filter[positions]=only_simple`](/api-reference/wallets/get-wallet-fungible-positions) |
| Multichain balances | `GET /v1/allchains/address/{address}/balances/` | Same call (all chains by default) |
| DeFi positions | (not available) | [`GET /v1/wallets/{address}/positions/?filter[positions]=only_complex`](/api-reference/wallets/get-wallet-fungible-positions) |
| Net worth + 24h change | (sum `quote` across balance items) | [`GET /v1/wallets/{address}/portfolio`](/api-reference/wallets/get-wallet-portfolio) |
| Net worth over time | `GET /v1/{chainName}/address/{address}/portfolio_v2/` | [`GET /v1/wallets/{address}/charts/{period}`](/api-reference/wallets/get-wallet-balance-chart) |
| Transactions | `GET /v1/{chainName}/address/{address}/transactions_v3/page/{page}/` | [`GET /v1/wallets/{address}/transactions/`](/api-reference/wallets/get-wallet-transactions) |
| Multichain transactions | `GET /v1/allchains/transactions/` | Same call (all chains by default) |
| Single transaction | `GET /v1/{chainName}/transaction_v2/{txHash}/` | [`GET /v1/wallets/{address}/transactions/?filter[search_query]=…`](/api-reference/wallets/get-wallet-transactions) |
| Wallet PnL | (not available) | [`GET /v1/wallets/{address}/pnl`](/api-reference/wallets/get-wallet-pnl) |
| Token prices | `GET /v1/pricing/historical_by_addresses_v2/{chainName}/{quoteCurrency}/{address}/` | [`GET /v1/fungibles/by-implementation?implementation={chain}:{address}`](/api-reference/fungibles/get-fungible-asset-by-implementation) + [fungible chart](/api-reference/fungibles/get-a-chart-for-a-fungible-asset) |
| NFTs | `GET /v1/{chainName}/address/{address}/balances_nft/` | [`GET /v1/wallets/{address}/nft-positions/`](/api-reference/wallets/get-wallet-nft-positions) |
| Chains used by a wallet | `GET /v1/address/{address}/activity/` | Derive from `positions_distribution_by_chain` on [`/portfolio`](/api-reference/wallets/get-wallet-portfolio) |
| Real-time updates | (pipeline delivery to your warehouse) | [Transaction webhooks](/webhooks) |

<Tip>
  Prefer not to write code? The [Zerion CLI](/build-with-ai/zerion-cli) wraps the same endpoints with a one-shot `npx @zerion/cli init` flow, useful for quick experiments and AI agents.
</Tip>

## A note on chains

The biggest structural change is how you address chains:

* **GoldRush:** the chain is a path segment (`eth-mainnet`, `matic-mainnet`, `base-mainnet`), one chain per call, with separate `allchains` endpoints for cross-chain reads.
* **Zerion:** `GET /v1/wallets/{address}/...` returns every supported chain for the address by default, narrowed with `filter[chain_ids]=ethereum,base`. Chain IDs are plain lowercase names without the `-mainnet` suffix (`ethereum`, `polygon`, `base`, `solana`); see the [full list](/supported-blockchains).

So a per-chain loop over `eth-mainnet`, `matic-mainnet`, `base-mainnet` becomes a single Zerion call, with the chain of each row in `relationships.chain.data.id`.

## Token balances

GoldRush's `balances_v2` returns one item per token with `balance` (a raw integer string you divide by `10^contract_decimals`) and precomputed `quote_rate` / `quote`. Zerion returns a [JSON:API](https://jsonapi.org/) collection covering all chains at once, with `attributes.fungible_info` for metadata, `attributes.quantity.float` for the decimal-adjusted amount, and `attributes.value` for the USD value. The same endpoint accepts both EVM and Solana addresses.

<CodeGroup>
  ```javascript JavaScript (EVM) theme={null}
  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"}`);
  }
  ```

  ```javascript JavaScript (Solana) theme={null}
  const API_KEY = process.env.ZERION_API_KEY;
  const address = "6sEk1enayZBGFyNvvJMTP7qs5S3uC7KLrQWaEk38hSHH";

  const res = await fetch(
    `https://api.zerion.io/v1/wallets/${address}/positions/?currency=usd&filter[chain_ids]=solana&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"}`);
  }
  ```

  ```python Python (EVM) theme={null}
  import os, requests

  api_key = os.environ["ZERION_API_KEY"]
  address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

  res = requests.get(
      f"https://api.zerion.io/v1/wallets/{address}/positions/",
      params={
          "currency": "usd",
          "filter[positions]": "only_simple",
          "filter[trash]": "only_non_trash",
          "sort": "-value",
      },
      auth=(api_key, ""),
  )
  res.raise_for_status()

  for pos in res.json()["data"]:
      info = pos["attributes"]["fungible_info"]
      qty = pos["attributes"]["quantity"]["float"]
      value = pos["attributes"]["value"]
      chain = pos["relationships"]["chain"]["data"]["id"]
      print(f"{info['symbol']} on {chain}: {qty} = ${value:.2f}" if value else f"{info['symbol']} on {chain}: {qty}")
  ```

  ```bash cURL (EVM) theme={null}
  curl -g -u "YOUR_API_KEY:" \
    "https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/positions/?currency=usd&filter[positions]=only_simple&filter[trash]=only_non_trash&sort=value"
  ```

  ```bash cURL (Solana) theme={null}
  curl -g -u "YOUR_API_KEY:" \
    "https://api.zerion.io/v1/wallets/6sEk1enayZBGFyNvvJMTP7qs5S3uC7KLrQWaEk38hSHH/positions/?currency=usd&filter[chain_ids]=solana&filter[trash]=only_non_trash&sort=value"
  ```
</CodeGroup>

### Field mapping

| GoldRush (`items[].…`) | Zerion (`data[].attributes.…`) |
| - | - |
| `contract_ticker_symbol`, `contract_name` | `fungible_info.symbol`, `fungible_info.name` |
| `contract_address` (`is_native_token: true` for gas tokens) | `fungible_info.implementations[].address` (`null` for native) |
| `contract_decimals` | `fungible_info.implementations[].decimals` |
| `logo_urls.token_logo_url` | `fungible_info.icon.url` |
| `balance` (raw integer string) | `quantity.int` (raw integer string). Also `quantity.float` (decimal number) and `quantity.numeric` (decimal string), so you don't divide by `10^contract_decimals` yourself. |
| `quote_rate` | `price` |
| `quote` / `pretty_quote` | `value` (USD number; format client-side) |
| `quote_24h`, `quote_rate_24h` (values as of 24h ago; you compute the delta) | `changes.absolute_1d`, `changes.percent_1d` (the 24h change, precomputed) |
| `last_transferred_at` / `block_height` | `updated_at` / `updated_at_block` |
| `is_spam`, `no-spam` (query) | `flags.is_trash`, or filter server-side with `filter[trash]=only_non_trash` |
| `type` (`cryptocurrency` / `dust`) | No dust class. `filter[trash]` covers spam and dust-like junk. |
| `chain_name` (top-level, one chain per call) | `relationships.chain.data.id` (per row, all chains in one call) |

<Note>
  `price` and `value` are `null` for tokens without a reliable price. Guard for `null` before summing or formatting.
</Note>

## Net worth

GoldRush has no net-worth endpoint; you sum `quote` across balance items, chain by chain. Zerion's [`/portfolio`](/api-reference/wallets/get-wallet-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.

<CodeGroup>
  ```javascript JavaScript theme={null}
  const API_KEY = process.env.ZERION_API_KEY;
  const address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";

  const res = await fetch(
    `https://api.zerion.io/v1/wallets/${address}/portfolio?currency=usd`,
    { headers: { accept: "application/json", authorization: `Basic ${btoa(API_KEY + ":")}` } }
  );
  const { data } = await res.json();
  const a = data.attributes;

  console.log(`Net worth: $${a.total.positions.toFixed(2)}`);
  console.log(`24h change: $${a.changes.absolute_1d?.toFixed(2)} (${a.changes.percent_1d?.toFixed(2)}%)`);
  console.log("By chain:", a.positions_distribution_by_chain);
  console.log("By type:", a.positions_distribution_by_type);
  ```

  ```python Python theme={null}
  import os, requests

  api_key = os.environ["ZERION_API_KEY"]
  address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

  res = requests.get(
      f"https://api.zerion.io/v1/wallets/{address}/portfolio",
      params={"currency": "usd"},
      auth=(api_key, ""),
  )
  a = res.json()["data"]["attributes"]
  print(f"Net worth: ${a['total']['positions']:.2f}")
  print(f"24h change: {a['changes']['percent_1d']}%")
  print("By chain:", a["positions_distribution_by_chain"])
  print("By type:", a["positions_distribution_by_type"])
  ```

  ```bash cURL theme={null}
  curl -u "YOUR_API_KEY:" \
    "https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/portfolio?currency=usd"
  ```
</CodeGroup>

The per-chain breakdown replaces GoldRush's address activity endpoint (`/v1/address/{address}/activity/`) for the common "which chains does this wallet use" case: any chain with a non-zero entry in `positions_distribution_by_chain` is in use.

## Net worth over time

GoldRush's `portfolio_v2` returns per-token holdings over time, one chain per call, with OHLC buckets per day. Zerion's [`/charts/{period}`](/api-reference/wallets/get-wallet-balance-chart) returns the wallet's total value timeseries across all chains in one call, for periods from `hour` to `max` (full history).

```bash cURL theme={null}
curl -u "YOUR_API_KEY:" \
  "https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/charts/month?currency=usd"
```

| GoldRush (`portfolio_v2`) | Zerion (`/charts/{period}`) |
| - | - |
| `holdings[].timestamp` + `close.quote` (per token, per day) | `points[]` of `[timestamp, value]` (wallet total) |
| `days=30` (query) | `{period}` path segment (`hour`, `day`, `week`, `month`, `3months`, `6months`, `year`, `5years`, `max`) |
| One chain per call | All chains; narrow with `filter[chain_ids]` |

<Note>
  GoldRush's series is per token; Zerion's is the wallet total (scopeable by chain and by fungible via filters). For a single asset's price history, use the [fungible chart](/api-reference/fungibles/get-a-chart-for-a-fungible-asset).
</Note>

## Transactions

GoldRush's `transactions_v3` returns raw transactions with `log_events[]` (decoded event logs you interpret yourself) and native-value fields. Zerion's [`/transactions/`](/api-reference/wallets/get-wallet-transactions) returns enriched, human-readable transactions with a single decoded `operation_type`, a unified `transfers[]` array with token metadata and USD values inlined, fees, and the dApp when Zerion recognizes it. The same endpoint accepts both EVM and Solana addresses.

<CodeGroup>
  ```javascript JavaScript (EVM) theme={null}
  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) ?? "?"}`);
  }
  ```

  ```python Python (EVM) theme={null}
  import os, requests

  api_key = os.environ["ZERION_API_KEY"]
  address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

  res = requests.get(
      f"https://api.zerion.io/v1/wallets/{address}/transactions/",
      params={"currency": "usd", "page[size]": 20},
      auth=(api_key, ""),
  )
  for tx in res.json()["data"]:
      attrs = tx["attributes"]
      chain = tx["relationships"]["chain"]["data"]["id"]
      dapp_id = (tx["relationships"].get("dapp") or {}).get("data", {}).get("id")
      print(f"[{attrs['mined_at']}] {attrs['operation_type']} on {chain}")
      if dapp_id:
          print(f"  via {dapp_id}")
      for t in attrs["transfers"]:
          sign = "-" if t["direction"] == "out" else "+"
          symbol = (t.get("fungible_info") or {}).get("symbol", "NFT")
          val = t.get("value")
          print(f"  {sign}{t['quantity']['float']} {symbol} (${val:.2f})" if val else f"  {sign}{t['quantity']['float']} {symbol}")
  ```

  ```bash cURL (EVM) theme={null}
  curl -g -u "YOUR_API_KEY:" \
    "https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/transactions/?currency=usd&page[size]=20"
  ```

  ```bash cURL (Solana) theme={null}
  curl -g -u "YOUR_API_KEY:" \
    "https://api.zerion.io/v1/wallets/6sEk1enayZBGFyNvvJMTP7qs5S3uC7KLrQWaEk38hSHH/transactions/?currency=usd&filter[chain_ids]=solana&page[size]=20"
  ```
</CodeGroup>

### Field mapping

| GoldRush (`items[].…`) | Zerion (`data[].attributes.…`) |
| - | - |
| `tx_hash` | `hash` |
| `block_signed_at` / `block_height` | `mined_at` (ISO 8601) / `mined_at_block` |
| `successful` | `status` (`confirmed` / `failed`, plus `pending` before mining) |
| `from_address` / `to_address` | `sent_from` / `sent_to` |
| (no category; infer from `log_events`) | `operation_type` (always set: `trade`, `send`, `receive`, `approve`, `revoke`, `deposit`, `withdraw`, `mint`, `burn`, `claim`, `execute`, `deploy`, and so on) |
| `value` (native, raw) / `value_quote` | A `transfers[]` entry with `direction`, `quantity` and `value` (USD) |
| `log_events[]` (`decoded.name`, `decoded.params[]`, `sender_contract_ticker_symbol`, …) | `transfers[]` and `approvals` with `fungible_info` / `nft_info` inlined. Zerion decodes token movements for you; raw event logs are not returned. |
| `internal_transfers` (`with-internal=true`) | Internal value movements already appear in `transfers[]` |
| `fees_paid` / `gas_quote` / `pretty_gas_quote` | `fee.quantity.float` (native) / `fee.value` (USD) |
| `gas_spent`, `gas_price`, `gas_offered` | No direct equivalent. Zerion returns the fee as quantity and value, not gas mechanics. |
| (no equivalent) | `relationships.dapp.data.id` (dApp slug, e.g. `uniswap-v3`, present when Zerion identifies it) |

### Filter mapping

| GoldRush param | Zerion equivalent |
| - | - |
| `{chainName}` path segment (one chain per call) | `filter[chain_ids]=ethereum,base` (omit for all chains) |
| `/page/{page}/` path + `links.prev` / `links.next` | Follow `links.next` from the response |
| `before` / `after` cursors (`allchains/transactions`) | Follow `links.next` from the response |
| `addresses=0x…,0x…` (`allchains/transactions`, multi-address) | One address per call; for batches use [wallet sets](/api-reference/wallet-sets/get-wallet-set-fungible-positions) |
| `block-signed-at-asc=true` | Not supported; newest first |
| `transaction_v2/{txHash}` (single tx) | `filter[search_query]=0x…` (matches the hash; the wallet address is still required in the path) |
| `quote-currency=USD` | `currency=usd` (fiat and crypto units) |

## DeFi positions

GoldRush has no DeFi positions product; reconstructing staking, lending, or LP exposure means decoding protocol events yourself. On Zerion, they're one call: each position is a row under `/positions/?filter[positions]=only_complex`, tagged with `protocol`, `protocol_module` (`lending`, `staked`, `liquidity_pool`, `locked`, `rewards`, `vesting`, and so on), and `position_type` (including `loan` for borrowed assets).

<CodeGroup>
  ```javascript JavaScript theme={null}
  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"}`);
  }
  ```

  ```python Python theme={null}
  import os, requests

  api_key = os.environ["ZERION_API_KEY"]
  address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

  res = requests.get(
      f"https://api.zerion.io/v1/wallets/{address}/positions/",
      params={"currency": "usd", "filter[positions]": "only_complex", "sort": "-value"},
      auth=(api_key, ""),
  )
  for pos in res.json()["data"]:
      a = pos["attributes"]
      chain = pos["relationships"]["chain"]["data"]["id"]
      print(f"[{a.get('position_type')}] {a['name']} | {a.get('protocol')} ({a.get('protocol_module')}) on {chain}: {a['quantity']['float']} = ${a['value'] or 0:.2f}")
  ```

  ```bash cURL theme={null}
  curl -g -u "YOUR_API_KEY:" \
    "https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/positions/?currency=usd&filter[positions]=only_complex&sort=value"
  ```
</CodeGroup>

Group rows by `relationships.dapp.data.id` to reconstruct protocols, and by `group_id` to reconstruct LP pairs. Wallet-level totals per type (deposited, borrowed, staked, locked) are in [`/portfolio`](/api-reference/wallets/get-wallet-portfolio) → `positions_distribution_by_type`.

## Wallet PnL

GoldRush has no wallet PnL endpoint. Zerion's [`/pnl`](/api-reference/wallets/get-wallet-pnl) returns wallet-level PnL computed with FIFO: realized and unrealized gain, net invested, total fees, and external in/out flows. Scope it per token with `filter[fungible_ids]`, per chain with `filter[chain_ids]`, or per time window with `since` / `till`.

<CodeGroup>
  ```javascript JavaScript theme={null}
  const API_KEY = process.env.ZERION_API_KEY;
  const address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";

  const res = await fetch(
    `https://api.zerion.io/v1/wallets/${address}/pnl?currency=usd`,
    { headers: { accept: "application/json", authorization: `Basic ${btoa(API_KEY + ":")}` } }
  );
  const { data } = await res.json();
  const a = data.attributes;

  console.log(`Realized gain:   $${a.realized_gain?.toFixed(2)}`);
  console.log(`Unrealized gain: $${a.unrealized_gain?.toFixed(2)}`);
  console.log(`Net invested:    $${a.net_invested?.toFixed(2)}`);
  console.log(`Total fees:      $${a.total_fee?.toFixed(2)}`);
  ```

  ```python Python theme={null}
  import os, requests

  api_key = os.environ["ZERION_API_KEY"]
  address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

  res = requests.get(
      f"https://api.zerion.io/v1/wallets/{address}/pnl",
      params={"currency": "usd"},
      auth=(api_key, ""),
  )
  a = res.json()["data"]["attributes"]
  print(f"Realized gain:   ${a['realized_gain']:.2f}")
  print(f"Unrealized gain: ${a['unrealized_gain']:.2f}")
  print(f"Net invested:    ${a['net_invested']:.2f}")
  print(f"Total fees:      ${a['total_fee']:.2f}")
  ```

  ```bash cURL theme={null}
  curl -u "YOUR_API_KEY:" \
    "https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/pnl?currency=usd"
  ```
</CodeGroup>

See the [wallet PnL tracker recipe](/recipes/wallet-pnl-tracker) for a worked example.

## Token prices

GoldRush's pricing endpoint returns a daily price series per contract address, with the quote currency in the path. Zerion splits this into two calls: [`/fungibles/by-implementation`](/api-reference/fungibles/get-fungible-asset-by-implementation) for the live price with full asset metadata, and the [fungible chart](/api-reference/fungibles/get-a-chart-for-a-fungible-asset) for a timeseries.

<CodeGroup>
  ```javascript JavaScript theme={null}
  const API_KEY = process.env.ZERION_API_KEY;
  const implementation = "ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"; // USDC

  const res = await fetch(
    `https://api.zerion.io/v1/fungibles/by-implementation?implementation=${implementation}&currency=usd`,
    { headers: { accept: "application/json", authorization: `Basic ${btoa(API_KEY + ":")}` } }
  );
  const { data } = await res.json();
  const m = data.attributes.market_data;

  console.log(`${data.attributes.symbol}: $${m.price}`);
  console.log(`24h change: ${m.changes?.percent_1d?.toFixed(2)}%`);
  ```

  ```python Python theme={null}
  import os, requests

  api_key = os.environ["ZERION_API_KEY"]
  implementation = "ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"  # USDC

  res = requests.get(
      "https://api.zerion.io/v1/fungibles/by-implementation",
      params={"implementation": implementation, "currency": "usd"},
      auth=(api_key, ""),
  )
  a = res.json()["data"]["attributes"]
  m = a["market_data"]
  print(f"{a['symbol']}: ${m['price']}")
  print(f"24h change: {m['changes']['percent_1d']}%")
  ```

  ```bash cURL theme={null}
  curl -u "YOUR_API_KEY:" \
    "https://api.zerion.io/v1/fungibles/by-implementation?implementation=ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&currency=usd"
  ```
</CodeGroup>

### Field mapping

| GoldRush (pricing response) | Zerion (`data.attributes.…`) |
| - | - |
| `items[].price` / `pretty_price` (daily points) | Live price in `market_data.price`; timeseries via the [fungible chart](/api-reference/fungibles/get-a-chart-for-a-fungible-asset) |
| `from` / `to` (date range) | Chart `{period}` (`hour`, `day`, `week`, `month`, `3months`, `6months`, `year`, `5years`, `max`) |
| `{quoteCurrency}` path segment (fiat list) | `currency` query param (fiat and crypto units) |
| `contract_ticker_symbol`, `contract_name`, `contract_decimals` | `symbol`, `name`, `implementations[].decimals` |
| Multiple contract addresses per call (comma-separated) | One implementation per call. For a batch, page [`/v1/fungibles/`](/api-reference/fungibles/get-list-of-fungible-assets) and read `market_data.price` from each result. |
| (no equivalent) | `market_data.changes` (5m to 1y percent changes), `market_data.market_cap`, `market_data.total_supply`, `market_data.circulating_supply` |

## NFTs

GoldRush's `balances_nft` returns NFT holdings with tokenURI-derived `external_data`, one chain per call. The Zerion equivalent is [`/v1/wallets/{address}/nft-positions/`](/api-reference/wallets/get-wallet-nft-positions), which returns each holding with collection metadata and floor-price-based valuation across chains.

```bash cURL theme={null}
curl -g -u "YOUR_API_KEY:" \
  "https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/nft-positions/?currency=usd&page[size]=20"
```

| GoldRush (`items[].…`) | Zerion (`data[].attributes.…`) |
| - | - |
| `contract_address` | `nft_info.contract_address` |
| `nft_data[].token_id` | `nft_info.token_id` |
| `supports_erc` (list, e.g. `["erc20","erc721"]`) | `nft_info.interface` (`erc721` / `erc1155`) |
| `nft_data[].external_data` (`name`, `image`, …) | `nft_info.name`, `nft_info.content` |
| `contract_name` | `collection_info.name` |
| `balance` (quantity held) | `amount` |
| `floor_price_quote` | `value` (floor value); `price` is the floor price |
| `last_transfered_at` | `changed_at` |
| `is_spam` | `nft_info.flags.is_spam` |
| `{chainName}` (one chain per call) | `relationships.chain.data.id` (all chains in one call) |

## Pagination

Replace GoldRush's page-number paths and `before`/`after` cursors with Zerion's `links.next` URL. Each Zerion response includes a fully-formed next-page link you can fetch as-is.

```javascript theme={null}
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;
}
```

## Real-time updates

GoldRush's real-time offering centers on pipeline delivery of decoded chain data into your own infrastructure. If what you actually need is "tell me when this wallet transacts", Zerion offers [transaction webhooks](/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](/recipes/wallet-activity-alerts) for a working example.

## Differences from GoldRush

Most GoldRush wallet use cases have a direct Zerion equivalent, and DeFi positions and PnL are additions. A few things aren't covered, and others behave differently. Worth a scan before you cut over.

**Not supported today:**

* **Historical balance snapshots:** GoldRush returns balances at any block height (`block-height`, `cutoff-timestamp`) and per-token holdings over time (`portfolio_v2`). Zerion exposes wallet value over time via [`/charts/{period}`](/api-reference/wallets/get-wallet-balance-chart) and asset price history via the [fungible chart](/api-reference/fungibles/get-a-chart-for-a-fungible-asset), but not balance-at-block.
* **Token holders:** GoldRush's `token_holders_v2` lists a token's holders at any height. Zerion is wallet-centric and does not return holder lists.
* **Token approvals state:** GoldRush's approvals endpoint returns current allowances with value-at-risk scoring. Zerion surfaces `approve` / `revoke` transactions in wallet history, but has no current-allowance endpoint.
* **Raw log events:** GoldRush returns decoded event logs (`log_events[].decoded`) for arbitrary contracts. Zerion returns enriched transfers and approvals, not raw logs.
* **Gas analytics:** `transactions_summary` aggregates (total fees paid, average gas per transaction) have no Zerion equivalent.
* **Bitcoin and long-tail chains:** GoldRush covers 100+ chains including `btc-mainnet` and appchains. Zerion covers EVM chains and Solana; check the [supported chains list](/supported-blockchains) for the ones you rely on.

If any of these matter for your migration, [let us know](#get-in-touch). Your feedback helps shape our roadmap.

**Worth knowing:**

* **Authentication:** GoldRush uses `Authorization: Bearer <key>`. Zerion uses [HTTP Basic Auth](/authentication) with the API key as username and an empty password. Get a key at [dashboard.zerion.io](https://dashboard.zerion.io).
* **Chains:** GoldRush puts a `chainName` slug in the path (`eth-mainnet`), one chain per call. Zerion returns all supported chains by default and filters with plain names: `filter[chain_ids]=ethereum,base`. See [the note above](#a-note-on-chains).
* **Address input:** GoldRush resolves ENS and other name services in the path. Zerion expects the wallet address itself; resolve names before calling.
* **Response shape:** GoldRush wraps everything in `{data, error, error_message, error_code}` with `items[]` inside. Zerion uses [JSON:API](https://jsonapi.org/): payloads live under `data[].attributes` with related entities under `data[].relationships`, and errors use HTTP status codes (see [error handling](/error-handling)).
* **Amounts decimal-adjusted:** GoldRush balances are raw integer strings. Zerion returns `quantity.float` (decimal), `quantity.int` (raw), and `quantity.numeric` (decimal string) on every position and transfer.
* **No pretty-formatted strings:** GoldRush pairs each value with a `pretty_*` display string. Zerion returns numbers; format client-side.
* **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). `no_filter` can leave out a share token's own `wallet` row when a protocol position carries it as `receipt`. See [Deduplicating share tokens](/recipes/defi-positions#deduplicating-share-tokens) before you sum rows.
* **Decoded transactions:** GoldRush gives you raw `log_events` to interpret. Zerion always sets a decoded `operation_type` and inlines transfer metadata, so most client-side decoding code goes away.
* **Multiple wallets:** GoldRush's `allchains/transactions` accepts multiple addresses per call. Zerion reads one address per `/wallets/` call; for batches use the [wallet sets](/api-reference/wallet-sets/get-wallet-set-fungible-positions) endpoints.
* **Spam filtering:** GoldRush flags `is_spam` and gates with `no-spam`. Zerion uses `filter[trash]=only_non_trash`. See [spam filtering](/spam-filtering) for the full taxonomy.
* **Pagination:** GoldRush pages by page number in the path (with `links.prev`/`links.next`) or cursors on `allchains` endpoints. Zerion returns a fully-formed `links.next` URL you can fetch as-is. See [pagination](/pagination-and-filtering).

## Get in touch

Have a use case we don't cover or need assistance with the migration? Our team can help. Reach out via the chat widget on [dashboard.zerion.io](https://dashboard.zerion.io), or [email us](mailto:api@zerion.io).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.