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

# Track Solana liquidity additions and removals

> Query Solana liquidity history and stream LP additions and removals by token, pool, or wallet. Combine liquidity with swaps and wallet identity.

Load LP activity with the trade-history API, then subscribe to a liquidity room for live additions and removals. Keep token amounts as strings and reconcile live events with confirmed history.

<CardGroup cols={2}>
  <Card title="Query liquidity history" icon="https://mintcdn.com/solanatracker/l0aXlX5jJ7xpUiwY/icons/hugeicons/clock-rotate-left.svg?fit=max&auto=format&n=l0aXlX5jJ7xpUiwY&q=85&s=6e050ec7ad404eb7d73e83e569fc5362" href="#query-liquidity-history" width="24" height="24" data-path="icons/hugeicons/clock-rotate-left.svg">
    Combine swaps and liquidity, or request only liquidity transactions.
  </Card>

  <Card title="Stream liquidity live" icon="https://mintcdn.com/solanatracker/4PIKDaYde_747jyk/icons/hugeicons/radio.svg?fit=max&auto=format&n=4PIKDaYde_747jyk&q=85&s=3d831f22127d920a197c5ed9e009f7ee" href="#stream-liquidity-live" width="24" height="24" data-path="icons/hugeicons/radio.svg">
    Follow a token, a pool, or a liquidity provider with five room scopes.
  </Card>
</CardGroup>

## Query liquidity history

The four token trade-history routes accept `events` and `enrich`. Choose the scope you need:

```http theme={null}
GET /trades/{token}?events=all
GET /trades/{token}/{pool}?events=liquidity
GET /trades/{token}/by-wallet/{wallet}?events=all&enrich=identity
GET /trades/{token}/{pool}/{wallet}?events=liquidity&sortDirection=ASC
```

* **`events=trades`** is the default: buys and sells only.
* **`events=all`** returns swaps, liquidity additions, and liquidity removals in one chronological feed.
* **`events=liquidity`** returns only `add_liquidity` and `remove_liquidity` events.
* **`enrich=identity`** adds current wallet identity to each returned row, including available KOL profiles, tags, trading platforms, developer/pool labels, and SNS names. Unknown wallets return `identity: null`.

Every mode returns a **`trades` array**. These filters apply to the four token-scoped routes above, not the wallet-wide, whale/KOL, or perpetual endpoints.

<CodeGroup>
  ```bash Liquidity only theme={null}
  curl --get "https://data.solanatracker.io/trades/6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN" \
    --header "x-api-key: YOUR_API_KEY" \
    --data-urlencode "events=liquidity" \
    --data-urlencode "enrich=identity" \
    --data-urlencode "limit=50"
  ```

  ```javascript Swaps and liquidity theme={null}
  const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN";
  const url = new URL(`https://data.solanatracker.io/trades/${token}`);
  url.search = new URLSearchParams({ events: "all", limit: "50" });

  const response = await fetch(url, {
    headers: { "x-api-key": "YOUR_API_KEY" },
  });
  if (!response.ok) throw new Error(`Request failed: ${response.status}`);
  const page = await response.json();

  for (const event of page.trades) {
    if (event.type === "add_liquidity" || event.type === "remove_liquidity") {
      console.log(event.type, event.pool, event.tokens);
    } else {
      console.log(event.type, event.amount, event.priceUsd);
    }
  }
  ```
</CodeGroup>

### Use the TypeScript SDK

Install `@solana-tracker/data-api` version **0.5.0 or later**. The history methods accept `events`, `enrich`, `limit`, and `sortDirection`; pass `nextCursor` back unchanged to load more activity.

```typescript theme={null}
import { Client } from '@solana-tracker/data-api';

const client = new Client({ apiKey: 'YOUR_API_KEY' });
const token = '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN';
const filters = {
  events: 'all',
  enrich: 'identity',
  limit: 100,
  sortDirection: 'DESC',
} as const;

const page = await client.getTokenTradeHistory(token, filters);
for (const event of page.trades) {
  if (event.type === 'add_liquidity' || event.type === 'remove_liquidity') {
    console.log(event.type, event.pool, event.tokens, event.identity);
  } else if (event.type === 'buy' || event.type === 'sell') {
    console.log(event.type, event.amount, event.volume);
  }
}

if (page.hasNextPage && page.nextCursor != null) {
  const nextPage = await client.getTokenTradeHistory(token, {
    ...filters,
    cursor: page.nextCursor,
  });
  console.log(nextPage.trades);
}
```

### Load the next page

Use `limit` from `1` to `500` (default `250`) and `sortDirection=DESC` for newest first or `ASC` for oldest first. For `events=all` and `events=liquidity`, `nextCursor` is an **opaque string**. Pass it back unchanged with the same token, pool, wallet, `events`, and `sortDirection`.

```javascript theme={null}
if (page.hasNextPage && page.nextCursor !== null) {
  url.searchParams.set("cursor", String(page.nextCursor));
  const nextResponse = await fetch(url, {
    headers: { "x-api-key": "YOUR_API_KEY" },
  });
  if (!nextResponse.ok) throw new Error(`Request failed: ${nextResponse.status}`);
  const nextPage = await nextResponse.json();
  console.log(nextPage.trades);
}
```

The cursor preserves multiple actions at the same timestamp. Do not replace it with the last event's time or reuse it after changing filters. Default trades-only requests retain their timestamp cursor; opt-in feeds also accept a numeric timestamp as an exclusive initial boundary.

`showMeta=true` adds token metadata to the **swap rows** only. Liquidity rows keep exact token amounts without swap prices, USD volume, or PnL. `hideArb` does not remove liquidity actions. Omit `enrich` when you do not need wallet identity.

## Stream liquidity live

Connect to `wss://datastream.solanatracker.io/{apiKey}` with your Data API key. Datastream is available on Premium, Business, and Enterprise plans.

### Choose a room

* **`liquidity:{mint}`** — all liquidity actions involving a token.
* **`liquidity:{mint}:{pool}`** — a token's activity in one pool.
* **`liquidity:{mint}:{pool}:{wallet}`** — one wallet's activity for that token and pool.
* **`liquidity:pool:{pool}`** — all liquidity actions in a pool.
* **`liquidity:wallet:{wallet}`** — a liquidity provider's activity across pools and tokens.

Replace the placeholders with Solana addresses. Join and leave use the same protocol as other Datastream rooms:

```javascript theme={null}
const token = "6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN";
const room = `liquidity:${token}`;
const ws = new WebSocket("wss://datastream.solanatracker.io/YOUR_API_KEY");

ws.onopen = () => {
  ws.send(JSON.stringify({ type: "join", room }));
};

ws.onmessage = ({ data }) => {
  const message = JSON.parse(data);
  if (message.type === "ping") {
    ws.send(JSON.stringify({ type: "pong" }));
    return;
  }
  if (message.type === "error") {
    console.error("Datastream error", message);
    return;
  }
  if (message.type !== "message" || message.room !== room) return;

  for (const event of message.data) {
    const action = event.type === "add_liquidity" ? "Added" : "Removed";
    for (const token of event.tokens) {
      console.log(`${action} ${token.amount} of ${token.address}`, event.pool);
    }
  }
};

// To unsubscribe while keeping the connection open:
// ws.send(JSON.stringify({ type: "leave", room }));
```

### Subscribe with the SDK

The SDK handles heartbeats and reconnects. Set `{ enriched: true }` for wallet labels, or omit it for the base room. Liquidity callbacks receive one event at a time.

```typescript theme={null}
import { Datastream } from '@solana-tracker/data-api';

const stream = new Datastream({
  wsUrl: 'wss://datastream.solanatracker.io/YOUR_API_KEY',
});
stream.on('error', console.error);
await stream.connect();

const sub = stream.subscribe.liquidity
  .token('6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', { enriched: true })
  .on((event) => {
    console.log(event.type, event.pool, event.tokens, event.identity);
  });

// sub.unsubscribe();
// stream.disconnect();
```

See the [Datastream protocol guide](/guides/datastream-protocol) for authentication errors, heartbeat handling, reconnecting, and resubscribing. Existing `transaction:*` rooms contain swaps; subscribe to liquidity rooms separately to show both kinds of activity.

### Add wallet identity to live events

Append **`:enriched`** to any liquidity room. The same suffix works on transaction, wallet, and whale/KOL rooms:

```json theme={null}
{ "type": "join", "room": "liquidity:6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN:enriched" }
```

With enrichment, events include `identity`. Unknown wallets return `null`. An incomplete lookup adds `identityStatus: "partial"`; that notification does not receive a later identity correction.

Enriched notifications can arrive later or in a different order. Identity reflects current, cached labels, not labels at the event's historical time. Token rooms use the requested token's identity context; pool and wallet liquidity rooms use the first non-quote token, or the first token if both are quote tokens.

## Read a liquidity event

The following is an illustrative payload. WebSocket messages wrap these events in `{ "type": "message", "room": "...", "data": [...] }`; REST returns them in `trades`.

```json theme={null}
{
  "tx": "TRANSACTION_SIGNATURE",
  "type": "add_liquidity",
  "program": "pumpfun-amm",
  "programId": "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA",
  "instruction": "deposit",
  "pool": "POOL_ADDRESS",
  "wallet": "LIQUIDITY_PROVIDER_ADDRESS",
  "time": 1789722000000,
  "slot": 370000000,
  "amountBasis": "transfer",
  "tokens": [
    {
      "address": "TOKEN_MINT",
      "amount": "123.000001",
      "amountRaw": "123000001",
      "decimals": 6
    },
    {
      "address": "So11111111111111111111111111111111111111112",
      "amount": "9.000000001",
      "amountRaw": "9000000001",
      "decimals": 9
    }
  ]
}
```

* **`type`** distinguishes `add_liquidity` and `remove_liquidity`. A rebalance can produce a separate removal and addition.
* **`pool`** is a single pool address. **`wallet`** is the owner or authority identified by the instruction, which can be a delegate or program-derived address.
* **`tokens[]`** contains the participating mints. One-sided operations can have one entry; zero amounts are omitted.
* **`amount`** is an exact decimal string; **`amountRaw`** is an integer string. Keep them as strings, or use decimal arithmetic and `BigInt`, to preserve precision.
* **`time`** is Unix milliseconds. **`slot`** identifies the Solana slot.
* **`amountBasis: "transfer"`** means gross token transfers across the pool vault, before Token-2022 withholding. It does not promise the net amount credited to a recipient.
* **`amountBasis: "principal"`** separates liquidity principal from fees or internal reallocations. Raydium CLMM removals can also include `feeAmountRaw` and `transferredAmountRaw` on each token.

<Note>
  Multiple actions can share a transaction signature, pool, and wallet. Do not collapse a feed to one event per signature. Internal event IDs are not exposed; use the returned cursor for REST pagination.
</Note>

## Live events and confirmed history

Live liquidity events are **provisional at processed commitment**. REST history contains confirmed/finalized activity using canonical block time, so its timestamp can differ from the live event. Provisional activity can disappear on a fork, and there is no rollback notification.

Overlapping subscriptions deliver activity through each matching room. A two-token action can appear in both token rooms and both token history feeds. Subscribe to the narrowest scope you need, and use REST history to reconcile your display after reconnecting.

## Supported liquidity activity

Supported instruction families include Raydium AMM v4, CPMM and CLMM; Orca Whirlpool; Pump AMM; Meteora DAMM v1/v2 and DLMM; Liquid Swap; and Futarchy. Coverage depends on the instruction and available on-chain data, rather than every funding action on every DEX.

Standalone fee/reward claims, LP token minting/burning, rent, and unrelated transfers are excluded. Bonding-curve swaps remain trades. Liquidity activity does not contribute to swap volume, price candles, or swap PnL.

## API reference

* [Liquidity room reference](/datastream/websockets/liquiditytoken)

* [Token trades](/data-api/trades/get-token-trades)

* [Pool-specific trades](/data-api/trades/get-pool-specific-trades)

* [Wallet-specific token trades](/data-api/trades/get-user-specific-token-trades)

* [Wallet-specific pool trades](/data-api/trades/get-user-specific-pool-trades)

* [Stream swaps alongside liquidity](/guides/live-transactions)
