Token Feed WebSocket Service

Real-time token feed service that provides updates about new and trending tokens with customizable filters.

WebSocket Endpoint

wss://api.solapi.live/ws/token-feed

Authentication is required using the x-api-key header.

Connection and Usage

1
Connect to the WebSocket endpoint

You'll receive a welcome message:

{
"type": "connected",
"message": "Connected to TokenFeed WebSocket. Send a JSON object with type:
      \"setFilters\" and filters."
}

2
Send your filter configuration

{
"type": "setFilters",
"filters": {
"Bot users": {
"min": 0,
"max": 50
},
"Buys": {
"min": 0,
"max": 1000
},
"Dev holding %": {
"min": 0,
"max": 20
},
"Exclude": {
"text": "rug,scam,honeypot"
},
"Holders": {
"min": 10,
"max": 1000
},
"Insider wallets supply": {
"min": 0,
"max": 50
},
"Liquidity": {
"min": 5000,
"max": 100000
},
"Market Cap": {
"min": 10000,
"max": 1000000
},
"Search": {
"text": "coin,token"
},
"Sells": {
"min": 0,
"max": 500
},
"Sniper wallets": {
"min": 0,
"max": 20
},
"Token Age (mins)": {
"min": 0,
"max": 60
},
"Top 10 Holders": false,
"Txns": {
"min": 0,
"max": 1000
},
"Volume": {
"min": 1000,
"max": 100000
},
"With at least 1 social": false
}
}

3
Receive confirmation

{
"type": "subscriptionConfirmed",
"message": "Filters applied"
}

4
Receive token updates

{
"event": "token",
"data": [{
"address": "TOKEN_ADDRESS",
"name": "dog and cat coin",
"symbol": "dac",
"buys": 55,
"totalTxns": 95,
"sells": 57,
"totalTxnsAdjusted": 152,
"buyVolume": 15313.36,
"sellVolume": 9600.07,
"totalVolume": 24913.43,
"price": "$0.00002248252",
"timestamp": "2025-04-30T15:23:36.000Z",
"type": "PUMP",
"createdAt": "2025-04-30T15:23:36.000Z",
"protocol": "PUMP",
"isDevRug": false,
"holders": 15,
"socialsCount": 22,
"botsTotalCount": 10,
"sniperWalletsCount": 17,
"buyTax": 1,
"sellTax": 1,
"links": {
"website": "https://example.com"
},
"liquidityUSD": 10164.86,
"devHoldingSupplyPerc": 0,
"top10HoldersSupplyPerc": null,
"insiderWalletsSupplyPerc": 38.698757573022405,
"isRenownedDev": true,
"marketCapUSD": 22482.52,
"isDevNew": false,
"riskScore": 9.0501934756161,
"chainId": []
}]
}

Example Usage

import WebSocket from 'ws';

const API_KEY = 'YOUR_API_KEY';

// Define comprehensive filters
const filters = {
    "Bot users": { min: 0, max: 50 },
    "Buys": { min: 0, max: 1000 },
    "Dev holding %": { min: 0, max: 20 },
    "Exclude": { text: "rug,scam,honeypot" },
    "Holders": { min: 10, max: 1000 },
    "Insider wallets supply": { min: 0, max: 50 },
    "Liquidity": { min: 5000, max: 100000 },
    "Market Cap": { min: 10000, max: 1000000 },
    "Search": { text: "coin,token" },
    "Sells": { min: 0, max: 500 },
    "Sniper wallets": { min: 0, max: 20 },
    "Token Age (mins)": { min: 0, max: 60 },
    "Top 10 Holders": false,
    "Txns": { min: 0, max: 1000 },
    "Volume": { min: 1000, max: 100000 },
    "With at least 1 social": false
};

// Create WebSocket connection with API key
const ws = new WebSocket('wss://api.solapi.live/ws/token-feed', {
    headers: {
        'x-api-key': API_KEY
    }
});

ws.on('open', () => {
    console.log('Connected to WebSocket server');
    // Send filter configuration
    const message = {
        type: "setFilters",
        filters: filters
    };
    ws.send(JSON.stringify(message));
});

ws.on('message', (data) => {
    try {
        const message = JSON.parse(data.toString());
        
        // Handle different message types
        if (message.type === 'connected' || message.type === 'subscriptionConfirmed') {
            console.log(message.message);
        } else if (message.type === 'error') {
            console.error('Error:', message.message);
        } else if (message.event === 'token') {
            // Format token data nicely
            message.data.forEach(token => {
                console.log('\nNew Token Update:');
                console.log('----------------');
                console.log(`Name: ${token.name} (${token.symbol})`);
                console.log(`Address: ${token.address}`);
                console.log(`Price: ${token.price}`);
                console.log(`Market Cap: $${token.marketCapUSD}`);
                console.log(`Liquidity: $${token.liquidityUSD}`);
                console.log(`Volume (24h): $${token.totalVolume}`);
                console.log(`Holders: ${token.holders}`);
                console.log(`Created: ${token.createdAt}`);
                console.log(`Risk Score: ${token.riskScore}`);
                console.log(`Type: ${token.type}`);
                console.log(`Protocol: ${token.protocol}`);
                
                // Trading stats
                console.log('\nTrading Stats:');
                console.log(`Buys: ${token.buys}`);
                console.log(`Sells: ${token.sells}`);
                console.log(`Total Txns: ${token.totalTxns}`);
                console.log(`Buy Tax: ${token.buyTax}%`);
                console.log(`Sell Tax: ${token.sellTax}%`);
                
                // Wallet stats
                console.log('\nWallet Stats:');
                console.log(`Bot Users: ${token.botsTotalCount}`);
                console.log(`Sniper Wallets: ${token.sniperWalletsCount}`);
                console.log(`Dev Holding: ${token.devHoldingSupplyPerc}%`);
                console.log(`Insider Supply: ${token.insiderWalletsSupplyPerc}%`);
                
                // Links
                if (token.links) {
                    console.log('\nLinks:');
                    Object.entries(token.links).forEach(([key, value]) => {
                        console.log(`${key}: ${value}`);
                    });
                }
                
                console.log('\n' + '-'.repeat(50));
            });
        }
    } 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);
});

Filter Fields

All filters are optional. Here's what each filter does:

FilterDescription
Bot usersFilter by number of bot wallets (min/max)
BuysFilter by number of buy transactions (min/max)
Dev holding %Filter by developer's token holding percentage (min/max)
ExcludeExclude tokens containing specific text (comma-separated)
HoldersFilter by number of holders (min/max)
Insider wallets supplyFilter by insider wallets supply percentage (min/max)
LiquidityFilter by liquidity in USD (min/max)
Market CapFilter by market cap in USD (min/max)
SearchSearch for tokens containing specific text (comma-separated)
SellsFilter by number of sell transactions (min/max)
Sniper walletsFilter by number of sniper wallets (min/max)
Token Age (mins)Filter by token age in minutes (min/max)
Top 10 HoldersFilter tokens with top 10 holders (true/false)
TxnsFilter by total number of transactions (min/max)
VolumeFilter by trading volume in USD (min/max)
With at least 1 socialFilter tokens with at least one social link (true/false)

Error Messages

If an error occurs, you'll receive a message in this format:

{
  "type": "error",
  "message": "Error description"
}

Common errors:

  • Invalid filter configuration
  • Invalid JSON format
  • Missing required fields
  • Authentication failure
  • Rate limit exceeded