Skip to main content
WS channel: wallet-positions Enabled on your key on request: contact us. The open positions of a wallet on a chain, kept up to date: the full list on subscribe, then each position as a trade changes it. Rows carry the same fields as REST /v1/wallet/positions: amount held, average entry and exit prices, realized PnL, bought and sold totals, token decimals and the wallet’s badges. One subscription is one wallet on one chain. For the same rows with their live USD value and unrealized PnL, use the Wallet Portfolio Stream: same parameters, same messages. For the trades themselves, the Wallet Trades Stream. positions is accepted as a channel name on subscribe; the ack and every event say wallet-positions.

Delivery model

  • Snapshot, then deltas. Right after the ack you receive a snapshot: every open position of the wallet on the chain. From then on you receive a delta each time a position changes.
  • At your pace. A change is pushed as soon as it happens. Changes that follow within your updatePeriod (100 ms by default) are grouped into the next message.
  • A fresh copy every minute. Every 60 s, if the positions or the USD rate moved, you receive the complete snapshot again ("reason": "periodic"), free: replace your list with it, like any snapshot.
  • Always consistent. Messages are numbered (seq, prev). Whenever the exact sequence cannot be delivered, you receive a fresh snapshot instead.

Parameters

string
required
Public chain id, evm:<id> or solana. Example: evm:8453
string
required
The wallet address (EVM hex, case-insensitive; Solana base58). Example: 0x9f1c3b6a2e5d4c7b8a9f0e1d2c3b4a5968778695
integer
Milliseconds, 0 to 60000, default 100: at most one delta per period, carrying every change of the period. The ack carries the value applied (snapped up to 0, 100, 250, 500, 1000, 2000, 5000, 10000, 30000, 60000). See Choosing your pace.

Messages

Every message is the data of an event frame.
  • enter: full rows of positions that open.
  • update: { "key": "<chain>:<token address>", … } with only the fields that changed. A field that became null is sent as null.
  • leave: the keys of the positions that closed.
  • summary: { positions, realizedPnlUsd } over the rows you hold, in every message.

Applying a delta

  1. Remove every key listed in leave.
  2. Apply every update: the fields present replace those of the row.
  3. Add every row of enter.
Rows are not ranked: keep them by key and sort them as you like. A snapshot replaces everything you hold. It carries up to 1,000 positions, the largest first; page through REST for more.

The row

The fields of REST /v1/wallet/positions, with the same names and the same null rules; token amounts are strings. Every USD figure drawn from the wallet’s trades (entry and exit prices, boughtUsd, soldUsd, realized PnL) follows the rule of REST: on Solana, at the rate of each trade; on EVM chains, at the chain’s current native price. amount is the wallet’s on-chain balance on both families: a transfer in or out moves it like a trade does.

Resume

Events carry a cursor. After a reconnect, send the same subscribe with "since": "<cursor>": you receive the deltas you missed, or a snapshot of the current positions followed by what comes next. Either way, applying what you receive is all there is to do. See Reconnect & resume in the Streams overview.

Billing

1 credit per message delivered. The snapshot of a subscription ("reason": "subscribe") costs 1, whatever its size; every delta costs 1, whatever it carries. Snapshots sent on our own after that first one ("reason": "periodic" every 60 s, "reason": "resync" after a hiccup) and deltas flagged "replay": true are free; the snapshot sent when you resume with since costs 1, like the one of a new subscription. A wallet that does not trade costs nothing, and the connection is free. A longer updatePeriod means fewer messages, and fewer credits. GET /v1/usage/breakdown reports this channel under WS wallet-positions, where requests is the number of messages delivered.

Errors

Close codes

Ack
type:object

Server acknowledgement: the subscription is live.

Snapshot
type:object

The complete view, in order: right after the ack ("reason": "subscribe", 1 credit), every 60 s if the view moved (periodic, free) and whenever the view has to be replaced (resync, free).

Delta
type:object

Each change of the view, at most one per updatePeriod: 1 credit per message.

Subscribe
type:object

Client frame opening the subscription (additive, ack is explicit).