Skip to content

A pool's positions

GET
/chains/solana/lp/pool/{address}/positions
curl --request GET \
--url 'https://api.getchord.xyz/v1/chains/solana/lp/pool/example/positions?status=open&limit=50'

The pool’s positions, most recently active first. Cached 20 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.
address
required

Solana address, base58, case-sensitive. Never lower-case it.

string
/^[1-9A-HJ-NP-Za-km-z]{32,44}$/

Pool address, base58.

status
string
default: all
Allowed values: open closed all

Which positions.

limit
integer
default: 50 >= 1 <= 200
Media typeapplication/json
object
chain
string
Allowed value: solana
pool

Solana address, base58, case-sensitive. Never lower-case it.

string
/^[1-9A-HJ-NP-Za-km-z]{32,44}$/
status
string
since

Unix time, seconds, UTC.

integer | null
positions
Array<object>

One Solana LP position.

object
position

Solana address, base58, case-sensitive. Never lower-case it.

string | null
/^[1-9A-HJ-NP-Za-km-z]{32,44}$/
dex

meteora_dlmm · meteora_damm_v2 · raydium_clmm · pumpswap.

string
pool

Solana address, base58, case-sensitive. Never lower-case it.

string | null
/^[1-9A-HJ-NP-Za-km-z]{32,44}$/
owner

Solana address, base58, case-sensitive. Never lower-case it.

string | null
/^[1-9A-HJ-NP-Za-km-z]{32,44}$/
mintA

Solana address, base58, case-sensitive. Never lower-case it.

string | null
/^[1-9A-HJ-NP-Za-km-z]{32,44}$/
symbolA

Creator-chosen.

string | null
mintB

Solana address, base58, case-sensitive. Never lower-case it.

string | null
/^[1-9A-HJ-NP-Za-km-z]{32,44}$/
symbolB

Creator-chosen.

string | null
lower

DLMM bin id or CLMM tick.

integer | null
upper
integer | null
status
string
Allowed values: open closed
openedAt

Unix time, seconds, UTC.

integer | null
closedAt

Unix time, seconds, UTC.

integer | null
firstEvent

Unix time, seconds, UTC.

integer
lastEvent

Unix time, seconds, UTC.

integer
events
integer
depositedA

Whole tokens.

number | null
depositedB
number | null
withdrawnA
number | null
withdrawnB
number | null
feesA

Claimed.

number | null
feesB

Claimed.

number | null
depositedUsd
number
withdrawnUsd
number
feesClaimedUsd
number
realizedPnlUsd

Withdrawn + fees − deposited; null unless closed, not partial and fully priced.

number | null
partial

The tape did not see the open (opened before since); PumpSwap: more came out than the tape saw going in.

boolean
unpricedEvents

Value events without a USD price.

integer
updatedAt

Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds).

integer
Example
{
"chain": "solana",
"pool": "HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR",
"status": "open",
"since": 1791301995,
"positions": [
{
"position": "6gDiPzm69sdQMAAMUjSwY8n1ruPXYpy6Yx5tTt3PBgPv",
"dex": "meteora_dlmm",
"pool": "HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR",
"owner": "GDzKV9YibjzWNtFCeGSAXntzv8e2tU1UcLPV1hoXxXJM",
"mintA": "So11111111111111111111111111111111111111112",
"symbolA": "SOL",
"mintB": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"symbolB": "USDC",
"lower": -21194,
"upper": -21170,
"status": "open",
"openedAt": 1791303634,
"closedAt": null,
"firstEvent": 1791303634,
"lastEvent": 1791303634,
"events": 2,
"depositedA": 0,
"depositedB": 65.188341,
"withdrawnA": 0,
"withdrawnB": 0,
"feesA": 0,
"feesB": 0,
"depositedUsd": 65.188341,
"withdrawnUsd": 0,
"feesClaimedUsd": 0,
"realizedPnlUsd": null,
"partial": false,
"unpricedEvents": 0
},
{
"position": "G8LWKkSM58cGfty8Huw7PAsaRz86LqyaysUhMLL8HdD3",
"dex": "meteora_dlmm",
"pool": "HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR",
"owner": "zmpMLRAH2Nt5ZDaax1jXH9QdmVRzw7rHm84sKpZa6wy",
"mintA": "So11111111111111111111111111111111111111112",
"symbolA": "SOL",
"mintB": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"symbolB": "USDC",
"lower": -21167,
"upper": -21091,
"status": "open",
"openedAt": 1791302020,
"closedAt": null,
"firstEvent": 1791302020,
"lastEvent": 1791303567,
"events": 25,
"depositedA": 22.506085353,
"depositedB": 1668.168769,
"withdrawnA": 16.697187434,
"withdrawnB": 1367.959384,
"feesA": 0.001835888,
"feesB": 0.267907,
"depositedUsd": 4385.0568295447565,
"withdrawnUsd": 3383.4942419848394,
"feesClaimedUsd": 0.48990795627555367,
"realizedPnlUsd": null,
"partial": false,
"unpricedEvents": 0
}
],
"updatedAt": 1791303662
}

BAD_ADDRESS / BAD_STATUS / BAD_LIMIT, or UNSUPPORTED_CHAIN (Solana is not public on this deployment and the request has no X-API-Key).

Media typeapplication/json

Every non-2xx body.

object
error
required

Stable machine code, e.g. INVALID_PARAMS, NOT_READY, RATE_LIMIT_EXCEEDED.

string
message

For humans.

string
statusCode

HTTP status, when included.

integer
Example
{
"error": "INVALID_PARAMS",
"message": "amount must be an integer string in the token's smallest unit"
}

Over the per-minute limit (RATE_LIMIT_EXCEEDED). Read X-RateLimit-Reset and back off.

Media typeapplication/json

Every non-2xx body.

object
error
required

Stable machine code, e.g. INVALID_PARAMS, NOT_READY, RATE_LIMIT_EXCEEDED.

string
message

For humans.

string
statusCode

HTTP status, when included.

integer
Example
{
"error": "INVALID_PARAMS",
"message": "amount must be an integer string in the token's smallest unit"
}

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.

Media typeapplication/json

Every non-2xx body.

object
error
required

Stable machine code, e.g. INVALID_PARAMS, NOT_READY, RATE_LIMIT_EXCEEDED.

string
message

For humans.

string
statusCode

HTTP status, when included.

integer
Example
{
"error": "INVALID_PARAMS",
"message": "amount must be an integer string in the token's smallest unit"
}