The positions channel sends every plain position move at the CTF base layer: collateral split into outcome positions, positions merged back, and payout redemptions. They come from the ConditionalTokens (CTF) contract and the CtfCollateralAdapter. We decode each one and send it after the transaction is confirmed on-chain.
The activity channel was removed; its events split between this channel and
combos. Module, neg-risk, and combinatorial position moves are on
combos. ERC-1155 transfers are on
transfers.
Subscribe
{
"action": "subscribe",
"id": "s1",
"channel": "positions"
}
With no filters, you get every confirmed base-layer position event from all markets.
Filters
| Filter | Type | Required | Description |
|---|
wallets | string[] | No | Hex addresses (0x…). Keeps events where a listed address is the initiator or holder. |
market_ids | string[] | No | Condition IDs as bytes32 hex strings. Keeps events for those markets. |
token_ids | string[] | No | Token IDs as decimal strings. Keeps events for the listed position tokens. |
market_ids and token_ids are one axis. min_usd is ignored here. See Filters for the combination rule.
Events
This channel sends all six base-layer position events. See Onchain Data for the part each event plays in the position and redemption lifecycle.
| Event | data.type | Description |
|---|
CtfPositionSplit | ctf_position_split | Collateral split into conditional token positions at the CTF base layer. |
CtfPositionsMerge | ctf_positions_merge | Conditional token positions merged at the CTF base layer. |
CtfPayoutRedemption | ctf_payout_redemption | Conditional tokens redeemed into payout collateral at the CTF base layer. |
CollateralPositionSplit | collateral_position_split | Collateral split into outcome positions. Shows a position being created at the collateral-adapter layer. |
CollateralPositionsMerged | collateral_positions_merged | Outcome positions merged back at the collateral layer. Shows a position being closed before redemption. |
PositionsRedeemed | positions_redeemed | A redemption at the collateral-adapter level. Links resolved conditions to the collateral that was paid out. |
Payloads
Every frame wraps the event in the standard envelope (type, id, channel, confirmed, data) shown on Frames. Below, each block is the data object for one event — its type discriminator plus every field the ABI decodes. A full frame looks like:
{
"type": "event",
"id": "s1",
"channel": "positions",
"confirmed": true,
"data": {
"type": "positions_redeemed",
"initiator": "0x…",
"conditionId": "0x…",
"…": "…"
}
}
The three ctf_* events come from the ConditionalTokens base layer and carry the full collateralToken / parentCollectionId context. The three collateral-adapter events are the higher-level wrapper and carry less.
ctf_position_split
PositionSplit on ConditionalTokens. Collateral (or a parent position) split into a set of outcome positions.
{
"type": "ctf_position_split",
"stakeholder": "0x…",
"collateralToken": "0x…",
"parentCollectionId": "0x…",
"conditionId": "0x…",
"partition": ["0x…", "0x…"],
"amount": "0x…"
}
| Field | Solidity type | Description |
|---|
type | string | ctf_position_split. |
stakeholder | address (hex) | Address that split the position. |
collateralToken | address (hex) | ERC-20 collateral backing the positions. |
parentCollectionId | bytes32 (hex) | Parent collection split from (zero for a top-level split). |
conditionId | bytes32 (hex) | Condition the split is on. |
partition | uint256[] (hex) | Index sets describing the outcome slots created. |
amount | uint256 (hex) | Amount of collateral or parent position split. |
ctf_positions_merge
PositionsMerge on ConditionalTokens. The inverse of a split — a set of outcome positions merged back into collateral or a parent position.
{
"type": "ctf_positions_merge",
"stakeholder": "0x…",
"collateralToken": "0x…",
"parentCollectionId": "0x…",
"conditionId": "0x…",
"partition": ["0x…", "0x…"],
"amount": "0x…"
}
| Field | Solidity type | Description |
|---|
type | string | ctf_positions_merge. |
stakeholder | address (hex) | Address that merged the positions. |
collateralToken | address (hex) | ERC-20 collateral backing the positions. |
parentCollectionId | bytes32 (hex) | Parent collection merged into (zero for top-level). |
conditionId | bytes32 (hex) | Condition the merge is on. |
partition | uint256[] (hex) | Index sets describing the outcome slots merged. |
amount | uint256 (hex) | Amount merged. |
ctf_payout_redemption
PayoutRedemption on ConditionalTokens. Resolved outcome tokens redeemed for their collateral payout.
{
"type": "ctf_payout_redemption",
"redeemer": "0x…",
"collateralToken": "0x…",
"parentCollectionId": "0x…",
"conditionId": "0x…",
"indexSets": ["0x…", "0x…"],
"payout": "0x…"
}
| Field | Solidity type | Description |
|---|
type | string | ctf_payout_redemption. |
redeemer | address (hex) | Address that redeemed the positions. |
collateralToken | address (hex) | ERC-20 collateral paid out. |
parentCollectionId | bytes32 (hex) | Parent collection of the redeemed positions. |
conditionId | bytes32 (hex) | Resolved condition being redeemed. |
indexSets | uint256[] (hex) | Index sets of the outcome slots redeemed. |
payout | uint256 (hex) | Total collateral paid out. |
collateral_position_split
PositionSplit on the CtfCollateralAdapter (also NegRiskCtfCollateralAdapter). The higher-level split — collateral into outcome positions.
{
"type": "collateral_position_split",
"initiator": "0x…",
"conditionId": "0x…",
"amount": "0x…"
}
| Field | Solidity type | Description |
|---|
type | string | collateral_position_split. |
initiator | address (hex) | Address that split the position. |
conditionId | bytes32 (hex) | Condition the split is on. |
amount | uint256 (hex) | Amount of collateral split. |
collateral_positions_merged
PositionsMerged on the CtfCollateralAdapter. The higher-level merge — outcome positions back into collateral.
{
"type": "collateral_positions_merged",
"initiator": "0x…",
"conditionId": "0x…",
"amount": "0x…"
}
| Field | Solidity type | Description |
|---|
type | string | collateral_positions_merged. |
initiator | address (hex) | Address that merged the positions. |
conditionId | bytes32 (hex) | Condition the merge is on. |
amount | uint256 (hex) | Amount merged. |
positions_redeemed
PositionsRedeemed on the CtfCollateralAdapter. A resolved condition paid out into collateral, with the per-outcome amounts redeemed.
{
"type": "positions_redeemed",
"initiator": "0x…",
"conditionId": "0x…",
"amounts": ["0x…", "0x…"],
"payout": "0x…"
}
| Field | Solidity type | Description |
|---|
type | string | positions_redeemed. |
initiator | address (hex) | Address that started the redemption. |
conditionId | bytes32 (hex) | Condition being redeemed. |
amounts | uint256[] (hex) | Amount redeemed for each outcome slot, in slot order. |
payout | uint256 (hex) | Total collateral paid out. |
Pending feed
Set confirmed: false on your subscribe to get the pending feed of this channel — the same payload shape for pending transactions sent to the CTF and collateral-adapter contracts, before they are in a block. Pending events are guesses. A transaction can be dropped, replaced, or reverted. See Mempool for the full frame shape and how to handle it.
{
"action": "subscribe",
"id": "pending",
"channel": "positions",
"confirmed": false
}
Last modified on July 5, 2026