Skip to main content
A position is one side of one market — the Yes token or the No token. positionId is the 32-bit integer Datadash uses to name it. It’s the join key behind activity rows, positions, holders and signals, and it’s the value every positionId filter expects.

How it’s built

Polymarket identifies each outcome by its CLOB token ID, a 256-bit integer. Datadash derives a compact uint32 from the market and the side instead:
Every market has exactly two outcomes, so 31 bits of market ID (about 2.1 billion markets) plus 1 bit of side covers every token. The mapping is 1:1 with the CLOB token ID — a position ID names exactly one token, and vice versa.
The compaction is why grouping and filtering are fast. A uint32 group key costs a fraction of the memory and CPU of a uint256 one across the profile and cohort queries.

Taking one apart

The market ID is the high 31 bits, the side is the low bit, and flipping that low bit gives you the opposite outcome in the same market.
Because the complement is a single XOR, “show me both legs of this market” needs no lookup: positionId and positionId ^ 1 are the pair.

Where it appears

In responses, positionId is carried on the resolved token object, alongside the CLOB tokenId and the market and event it belongs to:
tokenId is returned as a string, not a number — a 256-bit value does not survive JSON’s double-precision numbers. positionId is a plain integer. In filters, positionId accepts in and notIn, with a single value or an array:
It’s available on activity, all three positions endpoints, all three holders endpoints, user positions, and signal scores. See Filtering for operators and grouping.

Choosing between the IDs