Real-time vs HTTP
GET Method
Available in HTTP queriesUse the same filtering system in HTTP GET requests for simple queries.
POST Method
Available in HTTP queriesUse the same filtering system in HTTP POST requests for advanced configurations.
Overview
The Holders Stream provides real-time position tracking for token holders. It tracks holder positions directly from swap events and periodically resyncs from the database for accuracy.Protocol
Endpoint Details
- URL:
wss://api.mobula.io - Event Type:
holders
Subscription
Multiple Tokens
Parameters
tokens(required): Array of token subscription items, each containing:address(required): Token addressblockchain(required): Blockchain identifier (e.g.,"Solana","evm:8453")
sortBy(optional, default:"balance"): Controls how the top 100 holders are sorted. Accepts"balance"(sort by USD balance descending) or"realizedPnl"(sort by realized PnL descending). Use"realizedPnl"for a top traders viewsubscriptionId(optional): Unique identifier for your WebSocket connection. Auto-generated if not providedsubscriptionTracking(optional, default:false): Include subscription details in response logs for debuggingmaxUpdatesPerMinute(optional): Throttle the number ofupdatemessages sent per minute. For example,maxUpdatesPerMinute: 30limits updates to at most one every 2 seconds. Useful for reducing bandwidth on high-activity tokens. When not set, updates are sent as fast as they arrive (with a minimum 100ms batching interval)
Maximum 10 tokens per connection for optimal performance.
Message Types
init — Full snapshot on subscribe
Sent once when you subscribe. Contains the top 100 holders sorted by the sortBy criteria (balance by default, or realized PnL):
update — Single holder changed
Sent in real-time when a swap changes a holder’s position. Both the buyer and seller are updated:
update message is sent with tokenAmount: "0". The client should remove this holder from its list.
sync — Periodic full resync
Sent every 30 seconds with a fresh snapshot from the database (same format as init). Use this to reconcile any missed updates or drift:
Data Model
Each holder object contains the following fields:platform
Trading platform the wallet used (e.g., Photon, BullX, Maestro):
walletMetadata
Entity information from wallet labeling:
fundingInfo
Where the wallet’s initial funds came from:
Client Implementation
Key Features
- Trades-based tracking — Positions are updated from swap events in real-time, not from external services
- LP positions included — Liquidity pool addresses are tracked and updated with
isLiquidityPool: true - Both sides updated — On each swap, both the buyer (recipient) and seller (sender) positions are updated
- Post-balance accuracy — Uses on-chain post-balance from the swap for exact balance tracking
- Periodic resync — Automatic
syncfrom DB every 30s ensures consistency - Capped at 100 — Init and sync return top 100 holders, sorted by balance (default) or realized PnL via
sortBy
Connection Keepalive (Ping/Pong)
To maintain active WebSocket connections and prevent timeouts: Send ping:Unsubscribe
Unsubscribe from all holder streams
Unsubscribe from specific subscription
Support
Need help? Our response times are < 1h.Support
Telegram
Support
Slack
Need help?
Email