This endpoint is only available to Growth and Enterprise plans.

Real-time vs HTTP

Overview

Pulse Stream V2 introduces a new payload-based architecture that allows you to manage multiple views simultaneously with enhanced control over data flow and view management. Unlike the previous version, V2 sends separate payloads for each view and provides more granular control over subscriptions.

Key Features

  • Multiple Views: Subscribe to multiple custom views simultaneously
  • Payload-based Architecture: Each view receives its own payload with view-specific data
  • View Management: Pause/unpause individual views without disconnecting
  • Enhanced Filtering: Advanced filtering capabilities with real-time updates
  • Personalized IDs: Track multiple client sessions with custom identifiers
  • Factory Name Resolution: Automatic resolution of factory names to addresses

Endpoint Details

  • URL: wss://pulse-v2-api.mobula.io
  • Message format: JSON string
  • Architecture: Payload-based with view management

Basic Usage

Default Model Configuration

The simplest way to get started is using the default model, which automatically generates three predefined views without needing to specify them:
{
  "type": "pulse-v2",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "model": "default",
    "chainId": ["evm:8453", "solana:solana"],
    "poolTypes": ["moonshot-evm", "pumpfun"]
  }
}
This configuration automatically creates three views:
  1. new - New tokens sorted by creation date (descending)
    • Filters: created_at: { not: null }
    • Sort: created_at descending
    • Limit: 50 pools
  2. bonding - Tokens with market cap and volume activity
    • Filters: market_cap: { not: null }, volume_1h: { gte: 10 }
    • Sort: market_cap descending
    • Limit: 50 pools
  3. bonded - Tokens with bonding curves
    • Filters: created_at: { not: null }, bondingCurveAddress: { not: null }
    • Sort: created_at descending
    • Limit: 50 pools

Custom Views Configuration

For more control, you can define custom views:
{
  "type": "pulse-v2",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "views": [
      {
        "name": "new-tokens",
        "chainId": ["solana:solana"],
        "poolTypes": ["pumpfun"],
        "sortBy": "created_at",
        "sortOrder": "desc",
        "limit": 50
      },
      {
        "name": "trending",
        "chainId": ["evm:8453"],
        "poolTypes": ["moonshot-evm"],
        "sortBy": "volume_1h",
        "sortOrder": "desc",
        "limit": 30
      }
    ]
  }
}

Legacy Configuration (Auto-Generated Views)

You can also use the legacy format without specifying model: "default". When you provide chainId or poolTypes without any views, the system automatically generates the three default views:
{
  "type": "pulse-v2",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "chainId": ["evm:8453", "solana:solana"],
    "poolTypes": ["moonshot-evm", "pumpfun"]
  }
}
This is equivalent to using "model": "default" and will generate the same three views (new, bonding, bonded).

Personalized ID Support

Add a personalized identifier to track your connection:
{
  "type": "pulse-v2",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "personalizedId": "user_123_session_abc",
    "views": [
      {
        "name": "my-view",
        "chainId": ["evm:8453"],
        "poolTypes": ["moonshot-evm"]
      }
    ]
  }
}

View Configuration

For complete filter documentation including all available fields, operators, and examples, see Filter Details.

View Structure

Each view in the views array supports the following configuration:
{
  "name": "view-name",
  "chainId": ["evm:8453", "solana:solana"],
  "poolTypes": ["pumpfun", "moonshot-evm"],
  "sortBy": "volume_1h",
  "sortOrder": "desc",
  "limit": 30,
  "offset": 0,
  "excludeBonded": false,
  "filters": {
    "market_cap": { "gte": 1000 },
    "volume_1h": { "gte": 500 },
    "pools": {
      "factory": { "equals": "uniswap-v2" }
    }
  }
}

View Parameters

  • name (string, required): Unique identifier for the view
  • model (string, optional): Predefined model type (new, bonding, bonded) - overrides custom filters
  • chainId (string | string[]): Blockchains to monitor
  • poolTypes (string | string[]): Pool types/factories to monitor
  • sortBy (string): Sort field (see Filter Details)
  • sortOrder (string): Sort order (asc or desc)
  • limit (number): Number of results per view (max: 100)
  • offset (number): Offset for pagination
  • excludeBonded (boolean): Exclude bonded pools
  • filters (object): Filter configuration

Message Types

Initialization Messages

Init Message

Sent when a view is first created or when reconnecting:
{
  "type": "init",
  "payload": {
    "view-name": {
      "data": [
        {
          "price": 0.000123,
          "pair": {
            "token0": {...},
            "token1": {...}
          }
        }
      ]
    }
  }
}

Sync Message

Sent periodically to keep views synchronized:
{
  "type": "sync",
  "payload": {
    "view-name": {
      "data": [
        {
          "price": 0.000123,
          "pair": {
            "token0": {...},
            "token1": {...}
          }
        }
      ]
    }
  }
}

Real-time Update Messages

New Pool Message

Sent when a new pool is added to a view:
{
  "type": "new-pool",
  "payload": {
    "viewName": "view-name",
    "pool": {
      "price": 0.000123,
      "pair": {
        "token0": {...},
        "token1": {...}
      }
    }
  }
}

Pool Update Message

Sent when pool data is updated:
{
  "type": "update-pool",
  "payload": {
    "viewName": "view-name",
    "pool": {
      "price": 0.000124,
      "pair": {
        "token0": {...},
        "token1": {...}
      }
    }
  }
}

Pool Remove Message

Sent when a pool is removed from a view:
{
  "type": "remove-pool",
  "payload": {
    "viewName": "view-name",
    "poolAddress": "0x..."
  }
}

View Management

Pause Views

Pause specific views to reduce bandwidth usage:
{
  "type": "pulse-pause",
  "payload": {
    "action": "pause",
    "views": ["view-name-1", "view-name-2"]
  }
}

Unpause Views

Resume paused views:
{
  "type": "pulse-pause",
  "payload": {
    "action": "unpause",
    "views": ["view-name-1"]
  }
}

Unsubscribe

Disconnect from the stream:
{
  "type": "unsubscribe",
  "payload": {}
}

Advanced Examples

Multi-View Trading Analysis

{
  "type": "pulse-v2",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "personalizedId": "trading-analysis-001",
    "views": [
      {
        "name": "high-volume-new",
        "chainId": ["evm:8453"],
        "poolTypes": ["moonshot-evm"],
        "sortBy": "volume_1h",
        "sortOrder": "desc",
        "limit": 30,
        "filters": {
          "volume_1h": { "gte": 1000 },
          "market_cap": { "gte": 5000, "lte": 50000 },
          "buys_1h": { "gte": 20 },
          "sellers_1h": { "lte": 10 }
        }
      },
      {
        "name": "bonding-tokens",
        "chainId": ["solana:solana"],
        "poolTypes": ["pumpfun"],
        "sortBy": "market_cap",
        "sortOrder": "desc",
        "limit": 50,
        "excludeBonded": true,
        "filters": {
          "bonding_percentage": { "gte": 50 },
          "dev_holdings_percentage": { "lte": 10 },
          "top_10_holdings_percentage": { "lte": 30 }
        }
      },
      {
        "name": "trending-meme",
        "chainId": ["evm:8453", "solana:solana"],
        "poolTypes": ["moonshot-evm", "pumpfun"],
        "sortBy": "price_change_1h",
        "sortOrder": "desc",
        "limit": 25,
        "filters": {
          "pattern": "meme",
          "price_change_1h": { "gte": 10 },
          "volume_1h": { "gte": 500 },
          "min_socials": 2
        }
      }
    ]
  }
}

Holdings Analysis Dashboard

{
  "type": "pulse-v2",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "personalizedId": "holdings-dashboard",
    "views": [
      {
        "name": "low-concentration",
        "chainId": ["evm:8453"],
        "poolTypes": ["moonshot-evm"],
        "sortBy": "holders_count",
        "sortOrder": "desc",
        "limit": 40,
        "filters": {
          "top_10_holdings_percentage": { "lte": 20 },
          "top_50_holdings_percentage": { "lte": 40 },
          "snipers_holdings_percentage": { "lte": 5 },
          "holders_count": { "gte": 100 }
        }
      },
      {
        "name": "high-activity",
        "chainId": ["solana:solana"],
        "poolTypes": ["pumpfun"],
        "sortBy": "traders_1h",
        "sortOrder": "desc",
        "limit": 30,
        "filters": {
          "traders_1h": { "gte": 50 },
          "fees_paid_1h": { "gte": 100 },
          "volume_1h": { "gte": 2000 },
          "twitter_reuses_count": { "equals": 0 }
        }
      }
    ]
  }
}

Factory-Specific Monitoring

{
  "type": "pulse-v2",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "views": [
      {
        "name": "uniswap-v2-trending",
        "chainId": ["evm:1", "evm:56"],
        "poolTypes": ["uniswap-v2"],
        "sortBy": "volume_24h",
        "sortOrder": "desc",
        "limit": 50,
        "filters": {
          "pools": {
            "factory": { "equals": "uniswap-v2" }
          },
          "volume_24h": { "gte": 10000 },
          "liquidity": { "gte": 50000 }
        }
      },
      {
        "name": "pumpfun-new",
        "chainId": ["solana:solana"],
        "poolTypes": ["pumpfun"],
        "sortBy": "created_at",
        "sortOrder": "desc",
        "limit": 100,
        "filters": {
          "pools": {
            "type": { "equals": "pumpfun" }
          },
          "created_at": { "gte": "2024-01-01T00:00:00Z" }
        }
      }
    ]
  }
}

Data Model

Pool Data Schema

Each pool in the response follows the PoolDataSchema structure with comprehensive trading and analysis data:
interface PoolDataSchema {
  // Price Data
  price: number;
  price_change_1min: number;
  price_change_5min: number;
  price_change_1h: number;
  price_change_4h: number;
  price_change_6h: number;
  price_change_12h: number;
  price_change_24h: number;
  
  // Historical Prices
  price_1min_ago: number;
  price_5min_ago: number;
  price_1h_ago: number;
  price_4h_ago: number;
  price_6h_ago: number;
  price_12h_ago: number;
  price_24h_ago: number;
  
  // Market Data
  market_cap: number;
  created_at: Date | null;
  holders_count: number;
  
  
  // Volume Data
  volume_1min: number;
  volume_5min: number;
  volume_15min: number;
  volume_1h: number;
  volume_4h: number;
  volume_6h: number;
  volume_12h: number;
  volume_24h: number;
  
  // Trading Activity
  trades_1min: number;
  trades_5min: number;
  trades_15min: number;
  trades_1h: number;
  trades_4h: number;
  trades_6h: number;
  trades_12h: number;
  trades_24h: number;
  
  // Buy/Sell Breakdown
  buys_1min: number;
  buys_5min: number;
  buys_15min: number;
  buys_1h: number;
  buys_4h: number;
  buys_6h: number;
  buys_12h: number;
  buys_24h: number;
  
  sells_1min: number;
  sells_5min: number;
  sells_15min: number;
  sells_1h: number;
  sells_4h: number;
  sells_6h: number;
  sells_12h: number;
  sells_24h: number;
  
  // Unique Participants
  buyers_1min: number;
  buyers_5min: number;
  buyers_15min: number;
  buyers_1h: number;
  buyers_4h: number;
  buyers_6h: number;
  buyers_12h: number;
  buyers_24h: number;
  
  sellers_1min: number;
  sellers_5min: number;
  sellers_15min: number;
  sellers_1h: number;
  sellers_4h: number;
  sellers_6h: number;
  sellers_12h: number;
  sellers_24h: number;
  
  // Traders (Unique participants who both bought and sold)
  traders_1min: number;
  traders_5min: number;
  traders_15min: number;
  traders_1h: number;
  traders_4h: number;
  traders_6h: number;
  traders_12h: number;
  traders_24h: number;
  
  // Fees Paid
  fees_paid_1min: number;
  fees_paid_5min: number;
  fees_paid_15min: number;
  fees_paid_1h: number;
  fees_paid_4h: number;
  fees_paid_6h: number;
  fees_paid_12h: number;
  fees_paid_24h: number;
  
  // Token Information
  source: string | null;
  deployer: string | null;
  tokenSymbol: string | null;
  tokenName: string | null;
  dexscreenerListed: boolean | null;
  description: string | null;
  
  // Holdings Analysis
  devHolding: number;
  insidersHolding: number;
  snipersHolding: number;
  bundlersHolding: number;
  deployerMigrations: number;
  twitterReusesCount: number;
  proTradersHolding: number;
  top10Holding: number;
  top50Holding: number;
  top200Holding: number;
  
  // Pair Information
  pair: Pair;
  bondingPercentage: number;
  bonded: boolean;
  bondingCurveAddress: string | null;
  socials: {
    twitter: string | null;
    website: string | null;
    telegram: string | null;
    others: Record<string, unknown> | null;
  };
  description: string | null;
  top10percent: number;
  devHolder: number;
  holders_list: Array<{
    address: string;
    balance: number;
    nativeBalance: number;
    balanceUsd: number;
    boughtAmount: number;
    soldAmount: number;
    pnl: number;
  }>;
}

interface Pair {
  token0: Token;
  token1: Token;
  volume24h: number;
  liquidity: number;
  blockchain: string;
  address: string;
  createdAt: Date | null;
  type: string;
  baseToken: string;
  exchange: {
    name: string;
    logo: string;
  };
  factory: string | null;
  quoteToken: string;
  price: number;
  priceToken: number;
  priceTokenString: string;
  bonded?: boolean;
  bondingPercentage?: number;
  bondingCurveAddress?: string | null;
}

interface Token {
  address: string;
  price: number;
  priceToken: number;
  priceTokenString: string;
  approximateReserveUSD: number;
  approximateReserveTokenRaw: string;
  approximateReserveToken: number;
  symbol: string;
  name: string;
  id: number | null;
  decimals: number;
  totalSupply: number;
  circulatingSupply: number;
  logo: string | null;
  chainId: string;
  marketCap?: number;
  marketCapDiluted?: number;
}

Complete Response Example

{
  "type": "init",
  "payload": {
    "trending-view": {
      "data": [
        {
          "price": 0.000123,
          "price_change_1min": 2.5,
          "price_change_5min": 5.2,
          "price_change_1h": 12.8,
          "price_change_4h": 25.3,
          "price_change_6h": 18.7,
          "price_change_12h": 45.2,
          "price_change_24h": 67.8,
          
          "price_1min_ago": 0.000120,
          "price_5min_ago": 0.000117,
          "price_1h_ago": 0.000109,
          "price_4h_ago": 0.000098,
          "price_6h_ago": 0.000104,
          "price_12h_ago": 0.000085,
          "price_24h_ago": 0.000073,
          
          "market_cap": 123000,
          "created_at": "2024-01-15T10:30:00Z",
          "holders_count": 1450,
          
          "volume_1min": 1500,
          "volume_5min": 7500,
          "volume_15min": 18000,
          "volume_1h": 45000,
          "volume_4h": 120000,
          "volume_6h": 180000,
          "volume_12h": 350000,
          "volume_24h": 500000,
          
          "trades_1min": 25,
          "trades_5min": 120,
          "trades_15min": 280,
          "trades_1h": 650,
          "trades_4h": 1800,
          "trades_6h": 2500,
          "trades_12h": 4200,
          "trades_24h": 6800,
          
          "buys_1min": 15,
          "buys_5min": 75,
          "buys_15min": 180,
          "buys_1h": 420,
          "buys_4h": 1200,
          "buys_6h": 1700,
          "buys_12h": 2800,
          "buys_24h": 4500,
          
          "sells_1min": 10,
          "sells_5min": 45,
          "sells_15min": 100,
          "sells_1h": 230,
          "sells_4h": 600,
          "sells_6h": 800,
          "sells_12h": 1400,
          "sells_24h": 2300,
          
          "buyers_1min": 12,
          "buyers_5min": 58,
          "buyers_15min": 135,
          "buyers_1h": 320,
          "buyers_4h": 850,
          "buyers_6h": 1200,
          "buyers_12h": 2100,
          "buyers_24h": 3400,
          
          "sellers_1min": 8,
          "sellers_5min": 35,
          "sellers_15min": 75,
          "sellers_1h": 180,
          "sellers_4h": 450,
          "sellers_6h": 600,
          "sellers_12h": 1100,
          "sellers_24h": 1800,
          
          "traders_1min": 5,
          "traders_5min": 25,
          "traders_15min": 55,
          "traders_1h": 120,
          "traders_4h": 300,
          "traders_6h": 400,
          "traders_12h": 750,
          "traders_24h": 1200,
          
          "fees_paid_1min": 15.5,
          "fees_paid_5min": 75.2,
          "fees_paid_15min": 180.8,
          "fees_paid_1h": 450.5,
          "fees_paid_4h": 1200.3,
          "fees_paid_6h": 1800.7,
          "fees_paid_12h": 3500.2,
          "fees_paid_24h": 5000.8,
          
          "source": "pumpfun",
          "deployer": "0x1234567890abcdef...",
          "tokenSymbol": "DOGE",
          "tokenName": "Dogecoin",
          "dexscreenerListed": true,
          
          "devHolding": 8.2,
          "insidersHolding": 5.3,
          "snipersHolding": 3.8,
          "bundlersHolding": 2.1,
          "deployerMigrations": 0,
          "twitterReusesCount": 0,
          "proTradersHolding": 12.5,
          "top10Holding": 25.3,
          "top50Holding": 45.7,
          "top200Holding": 68.2,
          
          "pair": {
            "token0": {
              "address": "0x1234567890abcdef...",
              "price": 0.000123,
              "priceToken": 0.000123,
              "priceTokenString": "0.000123",
              "approximateReserveUSD": 25000,
              "approximateReserveTokenRaw": "203252032520325203252",
              "approximateReserveToken": 203252032520325203252,
              "symbol": "DOGE",
              "name": "Dogecoin",
              "id": 12345,
              "decimals": 18,
              "totalSupply": 1000000000,
              "circulatingSupply": 850000000,
              "logo": "https://example.com/logo.png",
              "chainId": "evm:8453",
              "marketCap": 104550,
              "marketCapDiluted": 123000
            },
            "token1": {
              "address": "0x4200000000000000000000000000000000000006",
              "price": 3200.50,
              "priceToken": 1,
              "priceTokenString": "1",
              "approximateReserveUSD": 20000,
              "approximateReserveTokenRaw": "6250000000000000000",
              "approximateReserveToken": 6.25,
              "symbol": "WETH",
              "name": "Wrapped Ether",
              "id": 67890,
              "decimals": 18,
              "totalSupply": 1000000,
              "circulatingSupply": 1000000,
              "logo": "https://example.com/weth-logo.png",
              "chainId": "evm:8453",
              "marketCap": 3200500000,
              "marketCapDiluted": 3200500000
            },
            "volume24h": 500000,
            "liquidity": 45000,
            "blockchain": "base",
            "address": "0xpool1234567890abcdef...",
            "createdAt": "2024-01-15T10:30:00Z",
            "type": "uniswap-v2",
            "baseToken": "token0",
            "exchange": {
              "name": "Uniswap V2",
              "logo": "https://example.com/uniswap-logo.png"
            },
            "factory": "0xfactory1234567890abcdef...",
            "quoteToken": "token1",
            "price": 0.000123,
            "priceToken": 0.000123,
            "priceTokenString": "0.000123",
            "bonded": false,
            "bondingPercentage": 0,
            "bondingCurveAddress": null
          },
          "bondingPercentage": 0,
          "bonded": false,
          "bondingCurveAddress": null,
          "socials": {
            "twitter": "https://twitter.com/dogecoin",
            "website": "https://dogecoin.com",
            "telegram": "https://t.me/dogecoin",
            "others": null
          },
          "description": "A revolutionary meme token",
          "top10percent": 25.3,
          "devHolder": 8.2,
          "holders_list": [
            {
              "address": "0xholder1234567890abcdef...",
              "balance": 1000000,
              "nativeBalance": 0.5,
              "balanceUsd": 123,
              "boughtAmount": 1500000,
              "soldAmount": 500000,
              "pnl": 23
            }
          ]
        }
      ]
    }
  }
}

Response Handling

Message Flow

  1. Connection: Send initial subscription with views configuration
  2. Init: Receive init message with current data for all views
  3. Updates: Receive real-time updates via new-pool, update-pool, and remove-pool messages
  4. Sync: Receive periodic sync messages to maintain data consistency
  5. Management: Use pause/unpause to control data flow

Error Handling

The API will send error messages in the following format:
{
  "type": "error",
  "payload": {
    "message": "Error description",
    "code": "ERROR_CODE"
  }
}

Reconnection Strategy

When reconnecting:
  1. Send the same subscription message
  2. Receive init message with current state
  3. Resume receiving real-time updates

Performance Considerations

View Limits

  • Maximum 10 views per connection
  • Maximum 100 pools per view
  • Maximum 1000 total pools across all views

Bandwidth Optimization

  • Use pause to reduce bandwidth when views are not needed
  • Filter aggressively to reduce data volume
  • Consider using limit to restrict pool count

Caching

  • Views are cached for 10 minutes when no clients are subscribed
  • Default views are always maintained
  • Factory name resolution is cached for performance

Support

Need help? Our response times are < 1h.