Holders Live WebSocket
Real-time holder data service for tokens via WebSocket connections.
WebSocket Endpoint
wss://api.solapi.live/ws/holders-liveAuthentication is required using the x-api-key header.
Connection and Subscription
1 Connect to the WebSocket endpoint
You'll receive a welcome message:
{
"type": "connected",
"message": "Connected to HoldersLive WebSocket. Send a JSON object with \"tokenAddress\"."
}2 Send subscription message
{
"tokenAddress": "YOUR_TOKEN_ADDRESS"
}3 Receive confirmation
{
"type": "subscriptionConfirmed",
"message": "Subscribed to TOKEN_ADDRESS"
}4 Receive real-time holder data
{
"event": "holder",
"address": "WALLET_ADDRESS",
"tokenAddress": "TOKEN_ADDRESS",
"currentAmount": "CURRENT_HOLDING_AMOUNT",
"holderSince": "2025-04-30T15:19:00.000Z",
"activity": {
"totalBought": {
"amount": "TOTAL_BOUGHT_AMOUNT",
"usd": "TOTAL_BOUGHT_USD",
"transactions": "NUMBER_OF_BUY_TRANSACTIONS"
},
"totalSold": {
"amount": "TOTAL_SOLD_AMOUNT",
"usd": "TOTAL_SOLD_USD",
"transactions": "NUMBER_OF_SELL_TRANSACTIONS"
}
},
"tags": ["TAG1", "TAG2"],
"nativeBalance": "NATIVE_TOKEN_BALANCE",
"syncedAt": "LAST_SYNC_TIMESTAMP"
}Holder Fields
| Field | Description |
|---|---|
| address | Wallet address of the holder |
| tokenAddress | Address of the token being held |
| currentAmount | Current amount of tokens held |
| holderSince | ISO 8601 timestamp when the wallet first held the token |
| activity.totalBought | Total buy activity (amount, USD value, and number of transactions) |
| activity.totalSold | Total sell activity (amount, USD value, and number of transactions) |
| tags | Array of tags associated with the holder |
| nativeBalance | Balance of the native token (e.g., SOL) |
| syncedAt | Last synchronization timestamp |
Example Usage
import WebSocket from 'ws';
const TOKEN_ADDRESS = 'HqygbqYQPBvMaxaCNenvvKUrEQsyJmBML2jueQSTpump';
const API_KEY = 'your-api-key-here';
console.log(`Starting WebSocket client for holders of token: ${TOKEN_ADDRESS}`);
// Create WebSocket connection with API key
const ws = new WebSocket('wss://api.solapi.live/ws/holders-live', {
headers: {
'x-api-key': API_KEY
}
});
ws.on('open', () => {
console.log('Connected to WebSocket server');
// Send subscription message
const message = {
tokenAddress: TOKEN_ADDRESS
};
ws.send(JSON.stringify(message));
});
ws.on('message', (data) => {
try {
const message = JSON.parse(data.toString());
if (message.type === 'connected' || message.type === 'subscriptionConfirmed' || message.type === 'error') {
console.log(message.message);
} else {
// Format holder data nicely
console.log('Holder Update:');
console.log(JSON.stringify(message, null, 2));
}
} catch (error) {
console.error('Error parsing message:', error.message);
}
});
ws.on('error', (error) => {
console.error('WebSocket error:', error.message);
});
ws.on('close', (code, reason) => {
console.log('Disconnected');
});
// Handle SIGINT for graceful shutdown
process.on('SIGINT', () => {
console.log('Closing connection...');
ws.close();
process.exit(0);
});Error Handling
If an error occurs, you'll receive a message in this format:
{
"type": "error",
"message": "Error description"
}Common errors:
- Missing tokenAddress in subscription message
- Invalid JSON format
- Unauthorized API key
- Invalid token address format
Notes
- The WebSocket connection will send updates in real-time as holders change
- All token amounts are returned in the token's smallest unit
- Tag information is based on known wallet patterns and historical behavior
- Connection may be terminated after 24 hours of inactivity
- Maximum connections per API key is limited to 5 concurrent connections