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

# Get a Wallet's Transaction History

> Fetch and interpret a wallet's transactions with human-readable types and transfer details.

**What you'll build:**

* Fetch and display a wallet's transaction history with human-readable labels
* Filter transactions by type, chain, and date range
* Paginate through the full history

```
[2024-03-15T14:22:31+00:00] trade on ethereum
  via Uniswap
  -0.5 ETH ($1,060.00)
  +1200.0 USDC ($1,200.00)
  Fee: $12.45

[2024-03-14T09:10:05+00:00] receive on optimism
  +500.0 OP ($680.00)
  Fee: $0.02

[2024-03-13T18:45:12+00:00] deposit on ethereum
  via Aave
  -1000.0 USDC ($1,000.00)
  Fee: $8.33
```

**Time:** \~10 minutes

## Prerequisites

* A Zerion API key ([get one here](https://dashboard.zerion.io))
* A wallet address to query

## Steps

<Steps>
  ### Fetch recent transactions

  Use the [wallet transactions](/api-reference/wallets/get-wallet-transactions) endpoint to get a wallet's history.

  <CodeGroup>
    ```javascript JavaScript theme={null}
    const API_KEY = process.env.ZERION_API_KEY;
    const address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";
    const headers = {
      accept: "application/json",
      authorization: `Basic ${btoa(API_KEY + ":")}`,
    };

    const response = await fetch(
      `https://api.zerion.io/v1/wallets/${address}/transactions/?currency=usd&page[size]=10`,
      { headers }
    );
    if (!response.ok) throw new Error(`API error: ${response.status}`);

    const { data } = await response.json();

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

      console.log(`[${mined_at}] ${operation_type} on ${chain}`);
      if (application_metadata?.name) {
        console.log(`  via ${application_metadata.name}`);
      }
      for (const transfer of transfers) {
        const symbol = transfer.fungible_info?.symbol || "NFT";
        console.log(
          `  ${transfer.direction === "out" ? "-" : "+"}${transfer.quantity.float} ${symbol} (${transfer.value != null ? `$${transfer.value.toFixed(2)}` : "N/A"})`
        );
      }
      console.log(`  Fee: ${fee.value != null ? `$${fee.value.toFixed(2)}` : "N/A"}`);
    }
    ```

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

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

    response = requests.get(
        f"https://api.zerion.io/v1/wallets/{address}/transactions/",
        params={"currency": "usd", "page[size]": 10},
        auth=(api_key, ""),
    )

    for tx in response.json()["data"]:
        attrs = tx["attributes"]
        chain = tx["relationships"]["chain"]["data"]["id"]
        app = attrs.get("application_metadata", {})

        print(f"[{attrs['mined_at']}] {attrs['operation_type']} on {chain}")
        if app.get("name"):
            print(f"  via {app['name']}")
        for transfer in attrs["transfers"]:
            symbol = transfer.get("fungible_info", {}).get("symbol", "NFT")
            direction = "-" if transfer["direction"] == "out" else "+"
            val = transfer.get("value")
            print(f"  {direction}{transfer['quantity']['float']} {symbol} ({f'${val:.2f}' if val is not None else 'N/A'})")
        fee_val = attrs["fee"].get("value")
        print(f"  Fee: {f'${fee_val:.2f}' if fee_val is not None else 'N/A'}")
    ```

    ```bash cURL theme={null}
    curl -u "YOUR_API_KEY:" \
      "https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/transactions/?currency=usd&page[size]=10"
    ```
  </CodeGroup>

  Each transaction includes:

  * `operation_type` — the high-level action (trade, send, receive, deposit, etc.)
  * `transfers[]` — individual token movements with direction (`in`/`out`/`self`)
  * `fee` — gas fee paid, with USD value
  * `application_metadata` — the DApp involved (e.g., "Uniswap", "Aave")

  ### Filter by operation type

  To show only specific transaction types, use `filter[operation_types]`.

  ```bash theme={null}
  # Show only trades (swaps)
  curl -u "YOUR_API_KEY:" \
    "https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/transactions/?currency=usd&filter[operation_types]=trade"
  ```

  Available operation types:

  | Type       | Description                          |
  | ---------- | ------------------------------------ |
  | `send`     | Sent tokens to another address       |
  | `receive`  | Received tokens from another address |
  | `trade`    | Swapped tokens (e.g., on a DEX)      |
  | `deposit`  | Deposited into a DeFi protocol       |
  | `withdraw` | Withdrew from a DeFi protocol        |
  | `mint`     | Minted new tokens                    |
  | `burn`     | Burned tokens                        |
  | `approve`  | Approved token spending              |
  | `claim`    | Claimed rewards or airdrops          |
  | `execute`  | Generic smart contract interaction   |
  | `deploy`   | Deployed a smart contract            |

  ### Filter by chain and date range

  Narrow results to specific chains or time windows. The `filter[min_mined_at]` value is a **Unix timestamp in milliseconds**.

  ```bash theme={null}
  # Ethereum transactions since Feb 26, 2024 (1708905600000 ms)
  curl -u "YOUR_API_KEY:" \
    "https://api.zerion.io/v1/wallets/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/transactions/?currency=usd&filter[chain_ids]=ethereum&filter[min_mined_at]=1708905600000"
  ```

  ### Paginate through full history

  Use `links.next` from each response to fetch the next page.

  <CodeGroup>
    ```javascript JavaScript theme={null}
    async function getFullHistory(address) {
      const allTxs = [];
      let url = `https://api.zerion.io/v1/wallets/${address}/transactions/?currency=usd&page[size]=100`;

      while (url) {
        const response = await fetch(url, {
          headers,
        });
        const result = await response.json();
        allTxs.push(...result.data);
        url = result.links.next || null;
      }

      return allTxs;
    }
    ```

    ```python Python theme={null}
    def get_full_history(address):
        all_txs = []
        url = f"https://api.zerion.io/v1/wallets/{address}/transactions/"
        params = {"currency": "usd", "page[size]": 100}

        while url:
            response = requests.get(url, params=params, auth=(api_key, ""))
            result = response.json()
            all_txs.extend(result["data"])
            url = result["links"].get("next")
            params = {}  # params are included in the next URL

        return all_txs
    ```
  </CodeGroup>

  ### Full working example

  Save as `tx-history.mjs` and run with `node tx-history.mjs`:

  ```javascript theme={null}
  const API_KEY = process.env.ZERION_API_KEY;
  const BASE_URL = "https://api.zerion.io/v1";
  const headers = {
    accept: "application/json",
    authorization: `Basic ${btoa(API_KEY + ":")}`,
  };

  async function getTransactions(address, { types, chains, limit } = {}) {
    const params = new URLSearchParams({ currency: "usd", "page[size]": limit || 20 });
    if (types) params.set("filter[operation_types]", types);
    if (chains) params.set("filter[chain_ids]", chains);

    const res = await fetch(
      `${BASE_URL}/wallets/${address}/transactions/?${params}`,
      { headers }
    );
    return res.json();
  }

  async function displayHistory(address) {
    const { data } = await getTransactions(address, { limit: 10 });

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

      console.log(`[${mined_at}] ${operation_type} on ${chain}`);
      if (application_metadata?.name) {
        console.log(`  via ${application_metadata.name}`);
      }
      for (const transfer of transfers) {
        const symbol = transfer.fungible_info?.symbol || "NFT";
        const dir = transfer.direction === "out" ? "-" : "+";
        console.log(`  ${dir}${transfer.quantity.float} ${symbol} (${transfer.value != null ? `$${transfer.value.toFixed(2)}` : "N/A"})`);
      }
      console.log(`  Fee: ${fee.value != null ? `$${fee.value.toFixed(2)}` : "N/A"}\n`);
    }
  }

  displayHistory("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045");
  ```
</Steps>

## Next steps

* Use `filter[asset_types]=nft` to show NFT transfers
* Combine with the [DApps endpoint](/api-reference/dapps/get-list-of-dapps) to enrich `application_metadata`
* Build real-time alerts using the [webhook recipe](/recipes/wallet-activity-alerts) instead of polling
