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

# From GoldRush

> 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, plus 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)                                                                                                          |
| Realtime 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;
}
```

## Realtime updates

GoldRush's realtime 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).
* **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 is happy to help! Reach out via the chat widget on [dashboard.zerion.io](https://dashboard.zerion.io), or [email us](mailto:api@zerion.io).
