---
title: "A wallet's LP positions"
method: GET
path: "/chains/solana/lp/wallet/{address}"
tags: ["Solana data"]
---

# A wallet's LP positions

`GET /chains/solana/lp/wallet/{address}`

## Request

- Base URL: `https://api.getchord.xyz/v1`
- URL: `https://api.getchord.xyz/v1/chains/solana/lp/wallet/{address}`
- Auth: none declared

The wallet's positions as owner (DLMM: the position's owner, not an operator acting for it), most recently active first, with totals over every position of the `status` asked: deposited, withdrawn, claimed fees, realized PnL and win rate over positions seen open to close. Cached 15 seconds.

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.

## Path parameters

- `address` string, required: Solana address, base58, case-sensitive. Never lower-case it.

## Query parameters

- `status` 'open' | 'closed' | 'all'
- `unit` 'usd' | 'native'
- `limit` integer

## Response `200`

- object
  - `chain` 'solana'
  - `wallet` string: Solana address, base58, case-sensitive. Never lower-case it.
  - `status` string
  - `since` integer, nullable: Unix time, seconds, UTC.
  - `positions` integer
  - `open` integer
  - `closed` integer
  - `pools` integer
  - `depositedUsd` number
  - `withdrawnUsd` number
  - `feesClaimedUsd` number
  - `realizedPnlUsd` number, nullable
  - `realizedPositions` integer
  - `winRate` number, nullable: 0–1.
  - `evUsd` number, nullable: Mean result of a realized position.
  - `avgAgeHours` number, nullable
  - `avgDepositUsd` number, nullable
  - `firstTs` integer, nullable: Unix time, seconds, UTC.
  - `lastTs` integer, nullable: Unix time, seconds, UTC.
  - `history` object[]: One row per day a position ended on, oldest first, whatever `status` was asked. Its sums are `realizedPnlUsd` and `feesClaimedUsd` of status=all.
    - `day` string: YYYY-MM-DD, UTC
    - `profitUsd` number: Result of the realized positions that ended on the day.
    - `feesUsd` number: Fees claimed by the positions that ended, or were last touched, on the day.
    - `positions` integer
  - `rows` SolLpPosition[]
    - `position` string, nullable: Solana address, base58, case-sensitive. Never lower-case it.
    - `dex` string: `meteora_dlmm` · `meteora_damm_v2` · `raydium_clmm` · `pumpswap`.
    - `pool` string, nullable: Solana address, base58, case-sensitive. Never lower-case it.
    - `owner` string, nullable: Solana address, base58, case-sensitive. Never lower-case it.
    - `mintA` string, nullable: Solana address, base58, case-sensitive. Never lower-case it.
    - `symbolA` string, nullable: Creator-chosen.
    - `mintB` string, nullable: Solana address, base58, case-sensitive. Never lower-case it.
    - `symbolB` string, nullable: Creator-chosen.
    - `lower` integer, nullable: DLMM bin id or CLMM tick.
    - `upper` integer, nullable
    - `status` 'open' | 'closed'
    - `openedAt` integer, nullable: Unix time, seconds, UTC.
    - `closedAt` integer, nullable: Unix time, seconds, UTC.
    - `firstEvent` integer: Unix time, seconds, UTC.
    - `lastEvent` integer: Unix time, seconds, UTC.
    - `events` integer
    - `depositedA` number, nullable: Whole tokens.
    - `depositedB` number, nullable
    - `withdrawnA` number, nullable
    - `withdrawnB` number, nullable
    - `feesA` number, nullable: Claimed.
    - `feesB` number, nullable: Claimed.
    - `depositedUsd` number
    - `withdrawnUsd` number
    - `feesClaimedUsd` number
    - `realizedPnlUsd` number, nullable: Withdrawn + fees − deposited; null unless closed, not partial and fully priced.
    - `partial` boolean: The tape did not see the open (opened before `since`); PumpSwap: more came out than the tape saw going in.
    - `unpricedEvents` integer: Value events without a USD price.
  - `updatedAt` integer: Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds).

## Other responses

- `400`: `BAD_ADDRESS` / `BAD_STATUS` / `BAD_LIMIT`, 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.

---

[API](https://skmtc.dev/getchord/apis/chord-api.md) · [All operations](https://skmtc.dev/getchord/apis/chord-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getchord/apis/chord-api/revisions/d3bc4640fea0?raw)
