get

/v4/analytics/positions/by-identifier/{chainId}/{identifier}

Get positions by opportunity identifier

Fetch the latest position for every user in a given opportunity.

Response:
- data[indexingId]: Wrapped positions keyed by indexingId. Each positionGroup carries shared metadata (protocol, action, stateType, globalStates, tokens) and a positions map keyed by positionId. Each position entry carries its user field; multiple users may share the same indexingId positionGroup.
- latest is reported as of the indexing checkpoint: its (blockNumber, blockTimestamp) are advanced to how far indexing has completed (state unchanged through there), never beyond it — so the state is never presented as more current than what's indexed.
- globalStates: at the positionGroup level it holds series descriptors only (type, indexingId) — fetch the values from GET /v4/analytics/global-states. This route returns raw states; it runs no global-state enrichment.
- display.unpricedReason (when valueUsd is absent): which step gave up — no_price (the token mapped but has no daily close at or before that day), no_token_mapped (no declared token denominates the amount, e.g. a market-keyed identifier), unresolved_amount (global-state enrichment produced none), unsupported_state (no valuation rule for the stateType). A price gap and an unsupported shape both read as "no value" without it.
- debt: present and true when the group's amounts are owed, not held (a borrow) — sum values across groups by subtracting these. Set once per group: it follows from the processor.
- positions[positionId].params: position-invariant fields hoisted out of the snapshots, emitted once per position. Shape follows stateType; CLAMM carries tickLower/tickUpper (and salt when the persisted state has one), which is why they are no longer inside each snapshot's state. poolId and tokenId are not emitted at all: poolId is the positionGroup's identifier, and tokenId is the last segment of the positionId key.
- pagination.positionCount: Total number of position entries returned
- pagination.recipientsCount: Number of distinct user addresses across all positions

Examples:
- Latest positions: GET /v4/analytics/positions/by-identifier/1/0xPoolAddress

Path parameters

chainIdnumber | string
required
identifierstring
required

Query parameters

includeDisplayboolean
required
default: false

Responses

200
Response for status 200
Schema
object
dataobject
required
Wrapped positions keyed by indexingId
paginationobject
required
positionCountnumber
required
Total number of position entries returned
recipientsCountnumber
required
Number of distinct user addresses in the response
Example
{
  "data": {},
  "pagination": {
    "positionCount": 0,
    "recipientsCount": 0
  }
}
get
https://analytics.merkl.xyz/v4/analytics/positions/by-identifier/{chainId}/{identifier}
Merkl Analytics API
curl -X GET "https://analytics.merkl.xyz/v4/analytics/positions/by-identifier/{chainId}/{identifier}"
Fill the required path parameters chainId, identifier to send.