> ## Documentation Index
> Fetch the complete documentation index at: https://docs.solanatracker.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Batch Operations

> Fetch PnL summaries and token positions for hundreds of Solana wallets or tokens in a single batch request — ideal for portfolio dashboards and screeners.

Use batch endpoints when you already know the wallets or tokens you want data for. They're built for dashboards, scanners, data pipelines, and bulk historical loading.

## When to Use Batch Endpoints

Batch endpoints are designed for scenarios where you need position data for **multiple entities at once**:

<CardGroup cols={3}>
  <Card title="Portfolio Tracker">
    Fetch a wallet's positions across 50+ tokens in one call
  </Card>

  <Card title="Token Dashboard">
    Get how 200 wallets performed on a specific token
  </Card>

  <Card title="Leaderboard Enrichment">
    Look up specific wallet+token pairs from leaderboard results
  </Card>
</CardGroup>

There are two kinds of batch endpoints:

* **Position batches** return token-level position rows and support `pnlMode`.
* **Wallet summary batch** returns wallet-level summaries and wallet tags for up to 100 wallets. It does not accept `pnlMode`.

***

## One Wallet, Many Tokens

Use [wallet batch positions](/data-api/pnl-v2/get-wallet-batch-positions) when you have one wallet and want to check multiple tokens at once.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://data.solanatracker.io/v2/pnl/wallets/{wallet}/positions/batch" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "tokens": [
        "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump",
        "84cAEWqiDsV5xXh6CB69Hi3HcnumBbdjH4THfyorpump",
        "CMx7yon2cLzHcXqgHsKJhuU3MmME6noWLQk2rAycBAGS"
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  const wallet = "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o";
  const tokens = [
    "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump",
    "84cAEWqiDsV5xXh6CB69Hi3HcnumBbdjH4THfyorpump"
  ];

  const res = await fetch(
    `https://data.solanatracker.io/v2/pnl/wallets/${wallet}/positions/batch`,
    {
      method: "POST",
      headers: {
        "x-api-key": "YOUR_API_KEY",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ tokens })
    }
  );
  const { positions, notFound } = await res.json();

  positions.forEach(p => {
    console.log(`${p.meta.symbol}: $${p.pnl.total.toFixed(2)} PnL`);
  });
  if (notFound.length) {
    console.log(`Not traded: ${notFound.join(", ")}`);
  }
  ```

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

  wallet = "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o"
  tokens = [
      "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump",
      "84cAEWqiDsV5xXh6CB69Hi3HcnumBbdjH4THfyorpump"
  ]

  res = requests.post(
      f"https://data.solanatracker.io/v2/pnl/wallets/{wallet}/positions/batch",
      json={"tokens": tokens},
      headers={"x-api-key": "YOUR_API_KEY"}
  )
  data = res.json()

  for p in data["positions"]:
      print(f"{p['meta']['symbol']}: ${p['pnl']['total']:.2f}")
  ```
</CodeGroup>

**Limit:** 100 tokens per request. Tokens the wallet never traded show up in the `notFound` array. Missing items are listed there; they are not request errors.

***

## Many Wallet Summaries

Use `POST /v2/pnl/wallets/batch` when you only need wallet-level summaries and tags, not per-token positions. The request accepts up to 100 unique wallet addresses. Invalid addresses are returned in `invalid`, wallets without a PnL summary are returned in `notFound`, and requests with more than 100 unique valid wallets include a `truncated` object.

```bash theme={null}
curl -X POST "https://data.solanatracker.io/v2/pnl/wallets/batch" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "wallets": [
      "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o",
      "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"
    ]
  }'
```

Each returned wallet mirrors the wallet-summary shape: `wallet`, `identity`, `summary`, `tags`, and `updatedAt`.

<Note>
  The batch response includes `summary` only. The `analysis` block from the single-wallet endpoint — including `analysis.winRate`, `analysis.tokens.profitable`, `analysis.tokens.losing`, `analysis.maxSinglePnl`, and the `ending` / `pnlAdjustments` fields — is **not** returned by `POST /v2/pnl/wallets/batch`. If you need `winRate` or any other `analysis.*` field for multiple wallets, call [`GET /v2/pnl/wallets/{wallet}`](/data-api/pnl-v2/get-wallet-summary) once per wallet.
</Note>

***

## One Token, Many Wallets

Use [token batch positions](/data-api/pnl-v2/get-token-batch-positions) to compare how multiple wallets performed on the same token.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://data.solanatracker.io/v2/pnl/tokens/{token}/positions/batch" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "wallets": [
        "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o",
        "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  const token = "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump";
  const wallets = [
    "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o",
    "vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"
  ];

  const res = await fetch(
    `https://data.solanatracker.io/v2/pnl/tokens/${token}/positions/batch`,
    {
      method: "POST",
      headers: {
        "x-api-key": "YOUR_API_KEY",
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ wallets })
    }
  );
  const { positions, notFound } = await res.json();

  positions.forEach(p => {
    console.log(`${p.wallet}: $${p.pnl.token.total.toFixed(2)} on this token, ${p.counts.total} trades`);
  });
  ```
</CodeGroup>

**Limit:** 200 wallets per request.

***

## Any Wallet-Token Pairs

[Position batch lookup](/data-api/pnl-v2/get-position-batch-lookup) handles arbitrary combinations when every pair is different.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://data.solanatracker.io/v2/pnl/positions/batch" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "pairs": [
        {
          "wallet": "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o",
          "token": "38PgzpJYu2HkiYvV8qePFakB8tuobPdGm2FFEn7Dpump"
        },
        {
          "wallet": "CyaE1VxvBrahnPWkqm5VsdCvyS2QmNht2UFrKJHga54o",
          "token": "84cAEWqiDsV5xXh6CB69Hi3HcnumBbdjH4THfyorpump"
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  const pairs = [
    { wallet: "CyaE1...", token: "38Pgz..." },
    { wallet: "CyaE1...", token: "84cAE..." },
    { wallet: "vines...", token: "38Pgz..." }
  ];

  const res = await fetch("https://data.solanatracker.io/v2/pnl/positions/batch", {
    method: "POST",
    headers: {
      "x-api-key": "YOUR_API_KEY",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ pairs })
  });
  const { positions, notFound } = await res.json();

  console.log(`Found ${positions.length} positions, ${notFound.length} not found`);
  ```
</CodeGroup>

**Limit:** 200 pairs per request.

***

## Which Endpoint to Use

| You want...                       | Endpoint                                                    | Limit       |
| --------------------------------- | ----------------------------------------------------------- | ----------- |
| One wallet's PnL across 50 tokens | [Wallet Batch](/data-api/pnl-v2/get-wallet-batch-positions) | 100 tokens  |
| 100 wallets' PnL on one token     | [Token Batch](/data-api/pnl-v2/get-token-batch-positions)   | 200 wallets |
| Specific wallet+token combos      | [Pair Batch](/data-api/pnl-v2/get-position-batch-lookup)    | 200 pairs   |
| Wallet summaries and tags         | `POST /v2/pnl/wallets/batch`                                | 100 wallets |

<Warning>
  Unmatched inputs come back in a `notFound` array instead of causing errors. Always check it.
</Warning>

## PnL Mode

All three **position** batch endpoints accept `?pnlMode=strict|adjusted|raw` as a query parameter. Default is `strict`. The wallet-summary batch endpoint does not accept `pnlMode`. See the [Essentials](/guides/pnl-v2/overview#essentials) for what each mode does.

```bash theme={null}
curl -X POST "https://data.solanatracker.io/v2/pnl/positions/batch?pnlMode=adjusted" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "pairs": [ ... ] }'
```

<CardGroup cols={2}>
  <Card title="Leaderboards" href="/guides/pnl-v2/leaderboards">
    Build a shortlist of wallets to batch-enrich.
  </Card>

  <Card title="Wallet Analysis" href="/guides/pnl-v2/wallet-analysis">
    Drill into a single wallet from your batch results.
  </Card>
</CardGroup>
