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

# Find every pool a token trades in

> List every pool a token trades in on one network with DexPaprika pool search: busiest first, cursor paging, and the move off the removed token pools endpoint.

## What you'll build

A list of every liquidity pool on one network that contains a given token, busiest first, with paging that walks the list as far as you need. That list is the input for three common jobs:

* Picking the pool to read a token's price or OHLCV history from
* Watching where a token's volume moves between DEXes
* Building a per-token dashboard that shows every venue at once

One call does it: `GET /networks/{network}/pools/search` with a `token_address` parameter.

<Warning>
  This call replaces `GET /networks/{network}/tokens/{token_address}/pools`, which was removed and now returns `410 Gone`. If you are migrating, the [before and after](#moving-off-the-removed-endpoint) section maps the old parameters to the new ones.
</Warning>

***

## The call

Every Solana pool that contains wrapped SOL, three busiest first:

```bash theme={null}
curl "https://api.dexpaprika.com/networks/solana/pools/search?token_address=So11111111111111111111111111111111111111112&order_by=volume_usd_24h&sort=desc&limit=3"
```

Four parameters do the work:

| Parameter                 | What it does                                                                                                                         |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `token_address`           | Keeps only pools that contain this token. One address per call.                                                                      |
| `order_by=volume_usd_24h` | Busiest pools first. Leave it out and the API still sorts by 24h volume; the `query` echo in the response shows which order applied. |
| `sort=desc`               | Direction. `asc` puts the quietest pools first.                                                                                      |
| `limit=3`                 | Rows per page, default 10. To see more, page with the cursor rather than raising this.                                               |

The network is part of the path, so the address is looked up on that chain only. The other search filters combine with `token_address` using AND: add `liquidity_usd_min` to skip thin pools, `dex_name` with the `dex_id` slug from a response to stay on one DEX, `created_after` to see only new venues. The [pool filtering tutorial](/tutorials/pool-filtering) lists them all.

<Note>
  `order_by` accepts `volume_usd_24h`, `volume_usd_7d`, `volume_usd_30d`, `liquidity_usd`, `txns_24h`, `created_at`, `price_usd`, `price_change_percentage_24h`, `price_change_percentage_6h`, `price_change_percentage_1h` and `price_change_percentage_5m`.
</Note>

***

## The response

The call above returned three rows. Here is one of them, with the other two cut for length; they have the same shape:

```json theme={null}
{
  "results": [
    {
      "id": "Czfq3xZZDmsdGdUyrNLtRhGc47cXcZtLG4crryfu44zE",
      "dex_id": "orca",
      "dex_name": "Orca",
      "chain": "solana",
      "volume_usd_24h": 168496953.16201064,
      "created_at": "2023-06-30T06:20:58Z",
      "created_at_block_number": 202532154,
      "transactions_24h": 112721,
      "price_usd": 100.60809068912208,
      "price_change_percentage_5m": -0.1062529142312169,
      "price_change_percentage_1h": 0.431175977902886,
      "price_change_percentage_6h": 0.5926833874484059,
      "price_change_percentage_24h": 3.36743033127382,
      "fee": null,
      "volume_usd_7d": 760412464.2545992,
      "volume_usd_30d": 4684625060.048196,
      "liquidity_usd": 24495221.15357559,
      "tokens": [
        { "id": "So11111111111111111111111111111111111111112", "chain": "solana", "has_image": true, "no_index": false },
        { "id": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "chain": "solana", "has_image": true, "no_index": false }
      ]
    }
  ],
  "has_next_page": true,
  "next_cursor": "eyJjaGFpbiI6InNvbGFuYSIsImZhY3RvcnlfaWQi...",
  "query": {
    "network": "solana",
    "limit": 3,
    "token_address": "So11111111111111111111111111111111111111112",
    "order_by": "volume_usd_24h",
    "sort": "desc"
  }
}
```

Field names as they come off the wire:

* `id` is the pool address. `dex_id` is the DEX slug and `dex_name` its label.
* `tokens` lists the pool's tokens by `id` only. A search row carries no symbol or name. When you need `SOL/USDC` rather than two addresses, call [pool details](/api-reference/pools/get-a-pool-on-a-network) for that `id`; its `tokens` array carries `symbol`, `name` and `decimals`.
* `query` echoes what the API applied. Read it after every call. It is how you know `token_address` was honoured and which `order_by` ran.
* `transactions_24h` is the trade count and `liquidity_usd` the pool's depth. Both are per pool, not per token.

***

## Network scope, one token per call, empty lists, thin pools

<Warning>
  **Network-scoped only.** The cross-network `GET /pools/search` accepts `token_address` and ignores it. The call returns `200`, its `query` echo drops the parameter, and the rows come from other chains too. To cover several networks, loop over them and make one per-network call each.
</Warning>

<Warning>
  **One token per query.** Repeating the parameter, as in `token_address=A&token_address=B`, is not a pair filter. The API keeps one of the values, and which one is not guaranteed by order. To find pools for a pair, filter on one token and check the `tokens` array for the other in your own code.
</Warning>

<Note>
  **An unknown address is not an error.** A wrong or mistyped address returns `200` with `"results": []`, `"has_next_page": false` and an empty `next_cursor`, and `query` still echoes the address you sent. An empty list usually means the address is wrong for that network, so check both before concluding the token has no pools. A token's address usually differs from chain to chain.
</Note>

<Note>
  **Volume and depth are different lists.** The busiest pool by `volume_usd_24h` can be a day-old pool with almost no liquidity. When you want the pool to price against, add a floor:

  ```bash theme={null}
  curl "https://api.dexpaprika.com/networks/solana/pools/search?token_address=So11111111111111111111111111111111111111112&liquidity_usd_min=1000000&order_by=volume_usd_24h&sort=desc&limit=3"
  ```
</Note>

***

## Paging with the cursor

The response above ended with `"has_next_page": true` and a `next_cursor`. Pass that value back as `cursor`, with every other parameter unchanged:

```bash theme={null}
BASE="https://api.dexpaprika.com/networks/solana/pools/search"
Q="token_address=So11111111111111111111111111111111111111112&order_by=volume_usd_24h&sort=desc&limit=3"

# Page one, keeping only the cursor
CURSOR=$(curl -s "$BASE?$Q" | python3 -c "import json, sys; print(json.load(sys.stdin)['next_cursor'])")

# Page two
curl -s "$BASE?$Q&cursor=$CURSOR"
```

Page two picks up below the last volume of page one, repeats no pool, still carries `has_next_page` and a fresh `next_cursor`, and every row still contains the token. Keep going until `has_next_page` is `false`. There are no page numbers.

Each page is one request and one credit, however many pools it returns. [Token details](/api-reference/tokens/get-a-tokens-latest-data-on-a-network) reports a token's pool count under `summary.pools`, and for a base asset like SOL it runs into the millions. Raise `limit` for fewer pages, add `liquidity_usd_min` to cut the tail, and stop at a page count you chose rather than at the end of the list. A free API key from [console.dexpaprika.com](https://console.dexpaprika.com) raises the limits on these calls; [pricing](https://dexpaprika.com/api/pricing) has the current quotas and the [rate limits page](/knowledge-base/rate-limits) explains how they are counted.

***

## Moving off the removed endpoint

Before:

```bash theme={null}
curl "https://api.dexpaprika.com/networks/solana/tokens/So11111111111111111111111111111111111111112/pools?order_by=volume_usd&sort=desc&limit=3"
```

That path now answers `410 Gone` with a body that names the replacement:

```json theme={null}
{
  "code": 410,
  "message": "endpoint removed",
  "replacement": "/networks/{network}/pools/search",
  "documentation": "https://api.dexpaprika.com/docs/#tag/Pools/operation/searchNetworkPools"
}
```

After:

```bash theme={null}
curl "https://api.dexpaprika.com/networks/solana/pools/search?token_address=So11111111111111111111111111111111111111112&order_by=volume_usd_24h&sort=desc&limit=3"
```

What moved where:

| Old                                                     | New                                                              |
| ------------------------------------------------------- | ---------------------------------------------------------------- |
| path `/networks/{network}/tokens/{token_address}/pools` | `/networks/{network}/pools/search?token_address={token_address}` |
| `order_by=volume_usd`                                   | `order_by=volume_usd_24h` (the default)                          |
| `page`                                                  | `cursor`, carrying `next_cursor` from the previous response      |
| `address` (second-token pair filter)                    | no equivalent; filter on one token and check `tokens` yourself   |
| `reorder` (pair-perspective flip)                       | no equivalent; rows are pool-perspective                         |
| response `pools` + `page_info`                          | `results` + `has_next_page` + `next_cursor`                      |

The [removed endpoint's reference page](/api-reference/tokens/get-top-x-pools-for-a-token) keeps the same table next to the old spec.

***

## Full example

The single call in curl, and a paged walk in Python and JavaScript that collects the busiest pools and prints what each one is paired with:

<CodeGroup>
  ```bash bash theme={null}
  curl "https://api.dexpaprika.com/networks/solana/pools/search?token_address=So11111111111111111111111111111111111111112&order_by=volume_usd_24h&sort=desc&limit=3"
  ```

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

  BASE = "https://api.dexpaprika.com/networks/solana/pools/search"
  SOL = "So11111111111111111111111111111111111111112"
  MAX_PAGES = 3

  params = {"token_address": SOL, "order_by": "volume_usd_24h", "sort": "desc", "limit": 100}
  pools = []

  for _ in range(MAX_PAGES):
      data = requests.get(BASE, params=params, timeout=30).json()
      pools.extend(data["results"])
      if not data["has_next_page"]:
          break
      params["cursor"] = data["next_cursor"]

  print(f"{len(pools)} pools contain {SOL[:6]}...")
  for pool in pools[:5]:
      other = next(t["id"] for t in pool["tokens"] if t["id"] != SOL)
      print(f"{pool['dex_name']:<14} {pool['id']}  paired with {other[:8]}...  ${pool['volume_usd_24h']:,.0f} 24h")
  ```

  ```javascript javascript theme={null}
  const BASE = "https://api.dexpaprika.com/networks/solana/pools/search";
  const SOL = "So11111111111111111111111111111111111111112";
  const MAX_PAGES = 3;

  const params = new URLSearchParams({ token_address: SOL, order_by: "volume_usd_24h", sort: "desc", limit: "100" });
  const pools = [];

  for (let page = 0; page < MAX_PAGES; page++) {
    const data = await (await fetch(`${BASE}?${params}`)).json();
    pools.push(...data.results);
    if (!data.has_next_page) break;
    params.set("cursor", data.next_cursor);
  }

  console.log(`${pools.length} pools contain ${SOL.slice(0, 6)}...`);
  for (const pool of pools.slice(0, 5)) {
    const other = pool.tokens.find((t) => t.id !== SOL)?.id ?? "?";
    console.log(`${pool.dex_name.padEnd(14)} ${pool.id}  paired with ${other.slice(0, 8)}...  $${Math.round(pool.volume_usd_24h).toLocaleString()} 24h`);
  }
  ```
</CodeGroup>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Pool filtering" icon="filter" href="/tutorials/pool-filtering">
    Every search filter, and how to combine them into a screener
  </Card>

  <Card title="Pool details" icon="water" href="/api-reference/pools/get-a-pool-on-a-network">
    Symbols, reserves and price stats for one pool id
  </Card>

  <Card title="Pool search reference" icon="code" href="/api-reference/pools/advanced-pool-filtering-on-a-specific-network">
    Every parameter and the full response schema
  </Card>

  <Card title="Historical data" icon="chart-line" href="/tutorials/retrieve-historical-data">
    OHLCV history for the pool you picked
  </Card>
</CardGroup>

### FAQs

<AccordionGroup>
  <Accordion title="Can I list a token's pools on every network in one call?">
    No. The `token_address` filter works on `GET /networks/{network}/pools/search` only. The cross-network `GET /pools/search` accepts the parameter and ignores it. Fetch the [network list](/api-reference/networks/get-a-list-of-available-blockchain-networks) and make one per-network call for each chain the token lives on.
  </Accordion>

  <Accordion title="Why do the rows show token addresses but no symbols?">
    Search rows carry each token's `id` and `chain` only. Call [pool details](/api-reference/pools/get-a-pool-on-a-network) with the pool `id` to get `symbol`, `name` and `decimals` for both tokens.
  </Accordion>

  <Accordion title="How do I find the pool for a token pair?">
    Filter on one token and check the `tokens` array for the other in your own code. Repeating `token_address` does not narrow the list to a pair. The API keeps one value, and which one is not guaranteed by order.
  </Accordion>

  <Accordion title="The list came back empty. Is the token unsupported?">
    An unknown address returns `200` with an empty `results` array rather than a `404`, so an empty list usually means the address does not exist on that network. Check that the address belongs to the chain in the path; a token's address usually differs from chain to chain.
  </Accordion>

  <Accordion title="What happened to /networks/{network}/tokens/{token_address}/pools?">
    It was removed and returns `410 Gone`. Use `GET /networks/{network}/pools/search?token_address={address}`. The `page` parameter became `cursor`, `order_by=volume_usd` became `order_by=volume_usd_24h`, and the `address` pair filter and `reorder` flag have no equivalent.
  </Accordion>
</AccordionGroup>
