# A pool's liquidity events

`GET https://api.getchord.xyz/v1/chains/solana/lp/pool/{address}/events`

Source: https://getchord.xyz/docs/api-reference/operations/sollppoolevents/

Adds, removes, fee claims, opens and closes, newest first. A close row of a DLMM `close_position2` or a Raydium CLMM position has no `pool`: the instruction does not carry it.

Liquidity on Solana from Chord's own tape: adds, removes, fee claims, position opens and closes, decoded from the same blocks as the swaps. No key needed.

- **Venues.** Meteora DLMM, Meteora DAMM v2, Raydium CLMM and PumpSwap. Orca Whirlpools, Raydium CPMM / v4 and Meteora dynamic pools are not read yet.
- **Since.** `since` is when LP decoding started (2026-10-06 15:53 UTC); windows never start before it. A position opened earlier is `partial: true` and carries no PnL.
- **Fees are claimed fees.** An LP's fees appear when it claims them, so a window's fees understate what the pool earned, and one claim can hold days of fees.
- **Positions.** One row per position account (DLMM / DAMM v2 position, Raydium CLMM position NFT, PumpSwap LP token account), rebuilt from all its events. `lower` / `upper` are DLMM bin ids or Raydium CLMM ticks; null = full range. Realized PnL = withdrawn + fees claimed − deposited, only for a position seen from its open to its close with every amount priced. An open position's current value is not in the events: none is given.
- **Amounts** are whole tokens in the pool's own order (`mintA` / `mintB`); USD is valued when the event happened. Each add / remove / claim is checked against the pool vaults' balance changes in the same transaction (`verified`).
- **Addresses** are base58 and case-sensitive, as on the other Solana routes.

## Parameters

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `address` | path | yes | string | Pool address, base58. |
| `limit` | query | no | integer (default `50`) |  |
| `before` | query | no | integer | Exclusive cursor, Unix seconds: rows strictly older than it. Pass the last row's `ts` for the next page. Several swaps can share a second, so a page boundary can skip the rest of that second: overlap with `ts + 1` and drop rows whose `tx` you already have. |

## Response 200

Example (captured from the live API):

```json
{
  "chain": "solana",
  "pool": "HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR",
  "events": [
    {
      "ts": 1791303634,
      "slot": 453953506,
      "signature": "5bPcr5RdHzhoYFECwNaxp6FFwiv1xCcMxkGhLfrzZJaHos6UWJdnCey9FgUhfUC8kZqLgsrBy2ifzw8b9oQsyajc",
      "dex": "meteora_dlmm",
      "kind": "add",
      "pool": "HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR",
      "position": "6gDiPzm69sdQMAAMUjSwY8n1ruPXYpy6Yx5tTt3PBgPv",
      "owner": "GDzKV9YibjzWNtFCeGSAXntzv8e2tU1UcLPV1hoXxXJM",
      "amountA": 0,
      "amountB": 65.188341,
      "usd": 65.188341,
      "lower": null,
      "upper": null,
      "verified": true
    },
    {
      "ts": 1791303634,
      "slot": 453953506,
      "signature": "5bPcr5RdHzhoYFECwNaxp6FFwiv1xCcMxkGhLfrzZJaHos6UWJdnCey9FgUhfUC8kZqLgsrBy2ifzw8b9oQsyajc",
      "dex": "meteora_dlmm",
      "kind": "open",
      "pool": "HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR",
      "position": "6gDiPzm69sdQMAAMUjSwY8n1ruPXYpy6Yx5tTt3PBgPv",
      "owner": "GDzKV9YibjzWNtFCeGSAXntzv8e2tU1UcLPV1hoXxXJM",
      "amountA": 0,
      "amountB": 0,
      "usd": null,
      "lower": -21194,
      "upper": -21170,
      "verified": null
    }
  ],
  "nextBefore": 1791303634
}
```

- **400**: `BAD_ADDRESS` / `BAD_LIMIT` / `BAD_CURSOR`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).
- **429**: Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.
- **503**: `CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer.
