This endpoint is only available to Growth and Enterprise plans.
Endpoint Details
Mobula now provides two dedicated WSS endpoints
Why? Because EVM and Solana work very differently under the hood. If we tried to send both through a single WebSocket channel, things would get messy:
- The event queue would get backed up under heavy traffic
- Messages would arrive slower or even drop
- Scaling would be harder since both ecosystems compete for the same resources
By keeping them separate, you get:
- Faster and more reliable streams
- Independent scaling (EVM traffic won’t affect Solana, and vice-versa)
- Stable event delivery, even when network activity spikes
You cannot mix Solana subscriptions on the EVM endpoint (and vice-versa).
Always use the correct endpoint for the chain you’re working with.
EVM Chains
- Endpoint:
wss://stream-evm-prod.mobula.io/
- Supported events:
swap, transfer, swap-enriched
- Subscription Payload:
This stream will capture all transfers & swaps and enriched swaps received by a specific address.
The EVM address in the filters must be lowercase.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "MyWalletEvmTransactions",
"chainIds": ["evm:6342"],
"events": ["swap", "transfer", "swap-enriched"],
"filters": { "eq": ["transactionTo", "0xd36b20c9dd8ffe68ed6078204dea8862d147193e"] },
"subscriptionTracking":"true"
}
}
SVM Chains
- Endpoint:
wss://stream-sol-prod.mobula.io/
- Supported events:
swap, transfer, swap-enriched
- Subscription Payload:
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "MyWalletEvmTransactions",
"chainIds": ["solana:solana"],
"events": ["swap", "transfer"],
"subscriptionTracking":"true"
}
}
Perpetuals (Perps) Chains
- Endpoint:
wss://stream-perps-prod.mobula.io/
- Supported events:
order
- Supported chains:
lighter:301, lighter:304, evm:42161 (Arbitrum for Gains Network)
The order event captures perpetual trading activity including market orders, liquidations, limit orders, take profits, and stop losses. See the Perps Data Model for full field reference.
Subscription Payload:
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "LighterLiquidations",
"chainIds": ["lighter:301", "lighter:304"],
"events": ["order"],
"filters": {
"or": [
{ "eq": ["type", "LIQUIDATION_LONG"] },
{ "eq": ["type", "LIQUIDATION_SHORT"] }
]
},
"subscriptionTracking": "true"
}
}
Available order types to filter on:
MARKET_BUY - Market buy orders
MARKET_SELL - Market sell orders
LIQUIDATION_LONG - Liquidated long positions
LIQUIDATION_SHORT - Liquidated short positions
LIMIT_BUY - Limit buy orders
LIMIT_SELL - Limit sell orders
TAKE_PROFIT - Take profit executions
STOP_LOSS - Stop loss executions
UPDATE_TP - Take profit updates
UPDATE_SL - Stop loss updates
LaunchpadStream
LaunchpadStream is a launchpad-focused mode of the Multi-Events Stream. It emits swaps and pool creations when the pool is a launchpad pool and was created within the requested time window.
- Endpoint: use the dedicated WSS endpoint for the chain family you track, for example
wss://stream-sol-prod.mobula.io/ for Solana.
- Supported event:
launchpad
- Response frame: every message uses the standard Multi-Events wrapper:
{ "data": ..., "chainId": ..., "duplicateCount": ..., "subscriptionId": ... }.
- Swaps:
data.event is swap. By default, data.swap is the unified fast-trade swap payload and data.token is the token-details state.
- Creations:
data.event is creation and data.creation is the new pool payload.
- No init/sync/remove: LaunchpadStream only emits live WebSocket events after subscription.
See the Launchpad Stream Data Model for the full response shape.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "FreshSolanaLaunchpads",
"chainIds": ["solana:solana"],
"events": ["launchpad"],
"createdWithinMinutes": 1440,
"tokenState": true,
"subscriptionId": "fresh-solana-launchpads",
"subscriptionTracking": true
}
}
By default, tokenState is true, so swap messages are wrapped in data with both swap and token. The token object is fetched from the token-details state right before the payload is sent. If token state is unavailable, token can be null.
{
"data": {
"event": "swap",
"swap": {
"event": "swap",
"pair": "CyHKMgQUqathJoFXHNmwULwW6rQCDupuabEw4vnuWtM2",
"date": 1780877914613,
"tokenPrice": 0,
"tokenPriceVs": 0,
"tokenAmount": 50678309.12766,
"tokenAmountVs": 0.839097327,
"tokenAmountUsd": 55.543780038760936,
"tokenNativePrice": 0,
"tokenMarketCapUSD": 0,
"type": "sell",
"operation": "mev",
"blockchain": "Solana",
"hash": "3x7RdppKRbydDdSgmwJKCDLuAzbDyaZ1zUJP6dVUU49rrw5ZntKcxHRGpCABijskKDxy1Kvz55Ny7nXutYriUSgC",
"sender": "Gygj9QQby4j2jryqyqBHvLP7ctv2SaANgh4sCb69BUpA",
"tokenAmountRaw": "50678309127660",
"tokenAmountRawVs": "839097327",
"subscriptionId": "fresh-solana-launchpads",
"timestamp": 1780877915727
},
"token": {
"address": "CiQx7YJKgs6fHNbPKivHzHinb1jWfH5VjEmLaNzjrtWb",
"chainId": "solana:solana",
"symbol": "GRIND",
"name": "GRIND",
"decimals": 6,
"priceUSD": 8.583804321194622e-7,
"marketCapUSD": 858.3804321194622,
"liquidityUSD": 826.4803145707567,
"poolAddress": "CyHKMgQUqathJoFXHNmwULwW6rQCDupuabEw4vnuWtM2",
"trades24h": 32,
"volume24hUSD": 813.8668634152958
}
},
"chainId": "solana:solana",
"duplicateCount": 1,
"subscriptionId": "fresh-solana-launchpads"
}
With tokenState: false, the token-details lookup is skipped and data is the flat unified fast-trade swap object:
{
"data": {
"event": "swap",
"pair": "CyHKMgQUqathJoFXHNmwULwW6rQCDupuabEw4vnuWtM2",
"date": 1780877914613,
"tokenPrice": 0,
"tokenPriceVs": 0,
"tokenAmount": 50678309.12766,
"tokenAmountVs": 0.839097327,
"tokenAmountUsd": 55.543780038760936,
"tokenNativePrice": 0,
"tokenMarketCapUSD": 0,
"type": "sell",
"operation": "mev",
"blockchain": "Solana",
"hash": "3x7RdppKRbydDdSgmwJKCDLuAzbDyaZ1zUJP6dVUU49rrw5ZntKcxHRGpCABijskKDxy1Kvz55Ny7nXutYriUSgC",
"sender": "Gygj9QQby4j2jryqyqBHvLP7ctv2SaANgh4sCb69BUpA",
"tokenAmountRaw": "50678309127660",
"tokenAmountRawVs": "839097327",
"subscriptionId": "fresh-solana-launchpads",
"timestamp": 1780877915727
},
"chainId": "solana:solana",
"duplicateCount": 1,
"subscriptionId": "fresh-solana-launchpads"
}
Creation messages use the same subscription and are sent when a new launchpad pool payload is received. tokenState does not change creation messages:
{
"data": {
"event": "creation",
"creation": {
"chainId": "solana:solana",
"justCreated": true,
"pool": {
"address": "CyHKMgQUqathJoFXHNmwULwW6rQCDupuabEw4vnuWtM2",
"type": "pumpfun",
"createdAt": "2026-06-08T00:18:18.000Z"
},
"token": {
"address": "CiQx7YJKgs6fHNbPKivHzHinb1jWfH5VjEmLaNzjrtWb",
"chainId": "solana:solana",
"symbol": "GRIND",
"name": "GRIND"
}
},
"subscriptionId": "fresh-solana-launchpads",
"timestamp": 1780877915727
},
"chainId": "solana:solana",
"duplicateCount": 1,
"subscriptionId": "fresh-solana-launchpads"
}
Usage Examples
Before diving into the examples, make sure to check the data models:
Pro Tip for Devs: Dive into these data models and experiment with filters — your imagination is the only limit! Mix and / or, combine keys, and watch your streams come alive!
- Explore
poolType, poolAddress, transactionFrom, transactionTo, and other keys in the data models.
- Combine multiple conditions using
and / or operators to capture exactly the events you want.
- Mix and match filters across swaps and transfers to suit your application needs.
Filter Swaps by Pools
This stream captures all swaps from either raydium or raydium-clmm pools.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "MyWalletSolTransactions",
"chainIds": ["solana:solana"],
"events": ["swap"],
"filters": {
"or": [
{"eq": ["poolType", "raydium"]},
{"eq": ["poolType", "raydium-clmm"]}
]
},
"subscriptionTracking":"true"
}
}
Filter Swap-Enriched by Pools
This stream captures all swap-enriched events from either raydium or raydium-clmm pools. The returned data is enriched, including:
- Derived swap view
- Base and quote token details
- Token metadata
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "MyWalletSolTransactions",
"chainIds": ["solana:solana"],
"events": ["swap-enriched"],
"filters": {
"or": [
{ "eq": ["poolType", "raydium"] },
{ "eq": ["poolType", "raydium-clmm"] }
]
},
"subscriptionTracking": "true"
}
}
Filter Transfer by Contract Address
This stream captures all swaps for a specific poolAddress and poolType.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "MyWalletSolTransactions",
"chainIds": ["solana:solana"],
"events": ["transfer"],
"filters": {
"and": [
{"eq": ["poolType", "pumpswap"]},
{"eq": ["poolAddress", "68L2iPWLtkRuxhHBYVJLSzaApBVuM6DNqLL1pEywbDGR"]}
]
},
"subscriptionTracking":"true"
}
}
Filter Transfers by Sender
This stream captures all transfers sent to a specific address.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "MyWalletTransactions",
"chainIds": ["solana:solana"],
"events": ["transfer"],
"filters": { "eq": ["transactionTo", "ASde6y8pBCU1aityWHRpqT7pEAcEonjCgFUMeh5egRes"] },
"subscriptionTracking":"true"
}
}
Filter Transfers From Sender and Receiver
This stream captures all transfers sent from or received by specific addresses.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "MyWalletSolTransactions",
"chainIds": ["solana:solana"],
"events": ["transfer"],
"filters": {
"or": [
{"eq": ["transactionFrom", "2zqLokC98qfedXyXZHeL4sEdFcmmTFizvb1UQeRweWxp"]},
{"eq": ["transactionTo", "suqh5sHtr8HyJ7q8scBimULPkPpA557prMG47xCHQfK"]}
]
},
"subscriptionTracking":"true"
}
}
Filter Swaps by Pool Address (Batch)
This stream listens for all swap events associated with one or more specific poolAddress values.
- Using the
"in" filter lets you efficiently capture swaps where the poolAddress matches any address in your provided list.
- You can also apply similar logic to other fields such as
from, to, or poolType — depending on what aspect of the swap you want to track.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "MyWalletEvmTransactions",
"chainIds": ["evm:8453"],
"events": ["swap"],
"filters": {
"or": [
{
"in": [
"poolAddress",
[
"0xd0b53d9277642d899df5c87a3966a349a798f224",
"0xedc625b74537ee3a10874f53d170e9c17a906b9c",
"0x76fa2b719cad87970ed6a5948abd23a474aa092cfd99ba362b7c9f53880f3cac"
]
]
}
]
},
"subscriptionTracking": "true"
}
}
Filter Swaps by Pool Type and Sender Address
This stream tracks all swap events that match specific poolType values and originate from one or more given swapSenderAddress values.
It’s perfect if you want to monitor swap activity from certain wallets while limiting results to specific pool categories (like Uniswap pools).
By combining "in" filters inside an "and" block, you can precisely define your tracking logic:
- Only capture swaps from specific wallet addresses
- AND make sure they belong to one of your target DEX pool types
This gives you a flexible way to analyze user trading behavior or build custom real-time monitoring systems.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "MyWalletEvmTransactions",
"chainIds": ["evm:8453"],
"events": ["swap"],
"filters": {
"and": [
{
"in": [
"poolType",
[
"uniswap-v2",
"uniswap-v4",
"uniswap-v3"
]
]
},
{
"in": [
"swapSenderAddress",
[
"0xd0b53d9277642d899df5c87a3966a349a798f224",
"0xa6b579684e943f7d00d616a48cf99b5147fc57a5",
"0xc88b2264d3ac0456a4863bf021de4e8ee1129a6b"
]
]
}
]
},
"subscriptionTracking": "true"
}
}
Filter Perps by Order Type (Liquidations)
This stream captures all liquidation events from Lighter perpetuals.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "LighterLiquidations",
"chainIds": ["lighter:301", "lighter:304"],
"events": ["order"],
"filters": {
"or": [
{ "eq": ["type", "LIQUIDATION_LONG"] },
{ "eq": ["type", "LIQUIDATION_SHORT"] }
]
},
"subscriptionTracking": "true"
}
}
Filter Perps by Exchange
This stream captures all perpetual orders from a specific exchange.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "GainsOrders",
"chainIds": ["evm:42161"],
"events": ["order"],
"filters": { "eq": ["exchange", "gains"] },
"subscriptionTracking": "true"
}
}
Filter Large Market Orders
This stream captures market buy and sell orders - useful for whale watching.
{
"type": "stream",
"authorization": "YOUR_API_KEY",
"payload": {
"name": "LargeMarketOrders",
"chainIds": ["lighter:301", "lighter:304"],
"events": ["order"],
"filters": {
"or": [
{ "eq": ["type", "MARKET_BUY"] },
{ "eq": ["type", "MARKET_SELL"] }
]
},
"subscriptionTracking": "true"
}
}
Parameters
chainIds (required): Array of blockchain identifiers - See supported chains
events (required): Array of event types - swap, transfer, swap-enriched, order (perps), launchpad
filters (optional): Filter conditions for events - See filter documentation
subscriptionId (optional): Unique identifier for your WebSocket connection. Auto-generated if not provided
subscriptionTracking (optional, default: false): Include subscription details in response logs for debugging
createdWithinMinutes (optional): For launchpad, only emits swaps and creations from launchpad pools created within this window
tokenState (optional, default: true): For launchpad swaps, wraps data as { "event": "swap", "swap": ..., "token": ... } and includes token-details state. Set to false for the flat swap object in data. This does not affect creation events
Implementation Example
const socket = new WebSocket("wss://stream-evm-prod.mobula.io/");
socket.addEventListener("open", () => {
socket.send(JSON.stringify({
type: "stream",
authorization: "YOUR_API_KEY",
payload: {
chainIds: ["evm:1", "evm:56"],
events: ["swap", "transfer"],
subscriptionTracking: true
}
}));
});
socket.addEventListener("message", (event) => {
const data = JSON.parse(event.data);
if (data.reorg) {
// Handle blockchain reorganization
console.log("Reorg detected:", data);
return;
}
// Process normal events
console.log("Event received:", data);
});
socket.addEventListener("error", (error) => {
console.error("WebSocket error:", error);
});
socket.addEventListener("close", () => {
console.log("WebSocket connection closed");
});
You can use the Network tab in your browser to see the WebSocket requests and responses in real-time.
Connection Keepalive (Ping/Pong)
To maintain active WebSocket connections and prevent timeouts, you can use the ping/pong mechanism:
Send ping:
Receive pong:
The server will respond with a pong message to confirm the connection is active.
Use ping messages periodically (every 30-60 seconds) to keep long-lived connections alive.
Unsubscribing from the Stream
Unsubscribe from All Streams
To terminate all active subscriptions on the current WebSocket connection:
{
"type": "unsubscribe",
"authorization": "YOUR_API_KEY",
"payload": {}
}
Unsubscribe from Specific Subscription
To unsubscribe from a specific subscription using its ID:
{
"type": "unsubscribe",
"authorization": "YOUR_API_KEY",
"payload": {
"subscriptionId": "your-subscription-id"
}
}
If you didn’t provide a subscriptionId when subscribing, one is auto-generated. To retrieve it, set "subscriptionTracking": true in the subscription payload.
Support
Can’t find what you’re looking for? Reach out to us, response times < 1h.