Skip to main content
POST
/
2
/
fast-search
Universal Search - POST (advanced filters)
curl --request POST \
  --url https://demo-api.mobula.io/api/2/fast-search \
  --header 'Content-Type: application/json' \
  --data '
{
  "input": "<string>",
  "chainId": "<string>",
  "poolTypes": "<string>",
  "filters": {},
  "sortBy": "volume24h",
  "sortOrder": "asc",
  "limit": 123,
  "offset": 123
}
'
{
  "data": [
    {
      "address": "<string>",
      "chainId": "<string>",
      "symbol": "<string>",
      "name": "<string>",
      "priceTokenString": "<string>",
      "approximateReserveTokenRaw": "<string>",
      "logo": "<string>",
      "bondedAt": "<string>",
      "createdAt": "<string>",
      "latestTradeDate": "<string>",
      "description": "<string>",
      "socials": {
        "twitter": "<string>",
        "website": "<string>",
        "telegram": "<string>",
        "others": {},
        "uri": "<string>"
      },
      "security": {
        "buyTax": "<string>",
        "sellTax": "<string>",
        "transferPausable": true,
        "top10Holders": "<string>",
        "isBlacklisted": true,
        "noMintAuthority": true,
        "balanceMutable": true,
        "lowLiquidity": "<string>",
        "burnRate": "<string>",
        "liquidityBurnPercentage": 123,
        "isHoneypot": true,
        "isNotOpenSource": true,
        "renounced": true,
        "locked": "<string>",
        "isWhitelisted": true,
        "isMintable": true,
        "modifyableTax": true,
        "selfDestruct": true
      },
      "liveStatus": "<string>",
      "liveThumbnail": "<string>",
      "livestreamTitle": "<string>",
      "liveReplyCount": 123,
      "decimals": 0,
      "id": null,
      "priceUSD": 0,
      "priceToken": 0,
      "approximateReserveUSD": 0,
      "approximateReserveToken": 0,
      "totalSupply": 0,
      "circulatingSupply": 0,
      "marketCapUSD": 0,
      "marketCapDilutedUSD": 0,
      "originLogoUrl": "<string>",
      "rank": null,
      "cexs": [],
      "exchange": {
        "name": "<string>",
        "logo": "<string>"
      },
      "factory": "<string>",
      "source": "<string>",
      "sourceFactory": "<string>",
      "sourceMetadata": {
        "name": "<string>",
        "logo": "<string>"
      },
      "sourceFactoryMetadata": {
        "name": "<string>",
        "logo": "<string>"
      },
      "liquidityUSD": 123,
      "liquidityMaxUSD": 123,
      "bonded": true,
      "bondingPercentage": 123,
      "bondingCurveAddress": "<string>",
      "preBondingFactory": "<string>",
      "poolAddress": "<string>",
      "blockchain": "<string>",
      "type": "<string>",
      "tokenType": "2020",
      "deployer": "<string>",
      "athUSD": 123,
      "atlUSD": 123,
      "athDate": "<string>",
      "atlDate": "<string>",
      "priceChange1minPercentage": 0,
      "priceChange5minPercentage": 0,
      "priceChange1hPercentage": 0,
      "priceChange4hPercentage": 0,
      "priceChange6hPercentage": 0,
      "priceChange12hPercentage": 0,
      "priceChange24hPercentage": 0,
      "poolPriceChange1minPercentage": 0,
      "poolPriceChange5minPercentage": 0,
      "poolPriceChange1hPercentage": 0,
      "poolPriceChange4hPercentage": 0,
      "poolPriceChange6hPercentage": 0,
      "poolPriceChange12hPercentage": 0,
      "poolPriceChange24hPercentage": 0,
      "liquidityBurnPercentage": 123,
      "volume1minUSD": 0,
      "volume5minUSD": 0,
      "volume15minUSD": 0,
      "volume1hUSD": 0,
      "volume4hUSD": 0,
      "volume6hUSD": 0,
      "volume12hUSD": 0,
      "volume24hUSD": 0,
      "volumeBuy1minUSD": 0,
      "volumeBuy5minUSD": 0,
      "volumeBuy15minUSD": 0,
      "volumeBuy1hUSD": 0,
      "volumeBuy4hUSD": 0,
      "volumeBuy6hUSD": 0,
      "volumeBuy12hUSD": 0,
      "volumeBuy24hUSD": 0,
      "volumeSell1minUSD": 0,
      "volumeSell5minUSD": 0,
      "volumeSell15minUSD": 0,
      "volumeSell1hUSD": 0,
      "volumeSell4hUSD": 0,
      "volumeSell6hUSD": 0,
      "volumeSell12hUSD": 0,
      "volumeSell24hUSD": 0,
      "trades1min": 0,
      "trades5min": 0,
      "trades15min": 0,
      "trades1h": 0,
      "trades4h": 0,
      "trades6h": 0,
      "trades12h": 0,
      "trades24h": 0,
      "buys1min": 0,
      "buys5min": 0,
      "buys15min": 0,
      "buys1h": 0,
      "buys4h": 0,
      "buys6h": 0,
      "buys12h": 0,
      "buys24h": 0,
      "sells1min": 0,
      "sells5min": 0,
      "sells15min": 0,
      "sells1h": 0,
      "sells4h": 0,
      "sells6h": 0,
      "sells12h": 0,
      "sells24h": 0,
      "buyers1min": 0,
      "buyers5min": 0,
      "buyers15min": 0,
      "buyers1h": 0,
      "buyers4h": 0,
      "buyers6h": 0,
      "buyers12h": 0,
      "buyers24h": 0,
      "sellers1min": 0,
      "sellers5min": 0,
      "sellers15min": 0,
      "sellers1h": 0,
      "sellers4h": 0,
      "sellers6h": 0,
      "sellers12h": 0,
      "sellers24h": 0,
      "traders1min": 0,
      "traders5min": 0,
      "traders15min": 0,
      "traders1h": 0,
      "traders4h": 0,
      "traders6h": 0,
      "traders12h": 0,
      "traders24h": 0,
      "feesPaid1minUSD": 0,
      "feesPaid5minUSD": 0,
      "feesPaid15minUSD": 0,
      "feesPaid1hUSD": 0,
      "feesPaid4hUSD": 0,
      "feesPaid6hUSD": 0,
      "feesPaid12hUSD": 0,
      "feesPaid24hUSD": 0,
      "totalFeesPaidUSD": 0,
      "totalFeesPaidNativeRaw": "0",
      "organicTrades1min": 0,
      "organicTrades5min": 0,
      "organicTrades15min": 0,
      "organicTrades1h": 0,
      "organicTrades4h": 0,
      "organicTrades6h": 0,
      "organicTrades12h": 0,
      "organicTrades24h": 0,
      "organicTraders1min": 0,
      "organicTraders5min": 0,
      "organicTraders15min": 0,
      "organicTraders1h": 0,
      "organicTraders4h": 0,
      "organicTraders6h": 0,
      "organicTraders12h": 0,
      "organicTraders24h": 0,
      "organicVolume1minUSD": 0,
      "organicVolume5minUSD": 0,
      "organicVolume15minUSD": 0,
      "organicVolume1hUSD": 0,
      "organicVolume4hUSD": 0,
      "organicVolume6hUSD": 0,
      "organicVolume12hUSD": 0,
      "organicVolume24hUSD": 0,
      "organicVolumeBuy1minUSD": 0,
      "organicVolumeBuy5minUSD": 0,
      "organicVolumeBuy15minUSD": 0,
      "organicVolumeBuy1hUSD": 0,
      "organicVolumeBuy4hUSD": 0,
      "organicVolumeBuy6hUSD": 0,
      "organicVolumeBuy12hUSD": 0,
      "organicVolumeBuy24hUSD": 0,
      "organicVolumeSell1minUSD": 0,
      "organicVolumeSell5minUSD": 0,
      "organicVolumeSell15minUSD": 0,
      "organicVolumeSell1hUSD": 0,
      "organicVolumeSell4hUSD": 0,
      "organicVolumeSell6hUSD": 0,
      "organicVolumeSell12hUSD": 0,
      "organicVolumeSell24hUSD": 0,
      "organicBuys1min": 0,
      "organicBuys5min": 0,
      "organicBuys15min": 0,
      "organicBuys1h": 0,
      "organicBuys4h": 0,
      "organicBuys6h": 0,
      "organicBuys12h": 0,
      "organicBuys24h": 0,
      "organicSells1min": 0,
      "organicSells5min": 0,
      "organicSells15min": 0,
      "organicSells1h": 0,
      "organicSells4h": 0,
      "organicSells6h": 0,
      "organicSells12h": 0,
      "organicSells24h": 0,
      "organicBuyers1min": 0,
      "organicBuyers5min": 0,
      "organicBuyers15min": 0,
      "organicBuyers1h": 0,
      "organicBuyers4h": 0,
      "organicBuyers6h": 0,
      "organicBuyers12h": 0,
      "organicBuyers24h": 0,
      "organicSellers1min": 0,
      "organicSellers5min": 0,
      "organicSellers15min": 0,
      "organicSellers1h": 0,
      "organicSellers4h": 0,
      "organicSellers6h": 0,
      "organicSellers12h": 0,
      "organicSellers24h": 0,
      "holdersCount": 123,
      "twitterReusesCount": 0,
      "twitterRenameCount": 0,
      "twitterRenameHistory": [],
      "deployerMigrationsCount": 0,
      "deployerTokensCount": 0,
      "dexscreenerListed": false,
      "dexscreenerHeader": null,
      "dexscreenerAdPaid": false,
      "dexscreenerAdPaidDate": null,
      "dexscreenerSocialPaid": false,
      "dexscreenerSocialPaidDate": null,
      "dexscreenerBoosted": false,
      "dexscreenerBoostedDate": null,
      "dexscreenerBoostedAmount": 0,
      "trendingScore1min": 0,
      "trendingScore5min": 0,
      "trendingScore15min": 0,
      "trendingScore1h": 0,
      "trendingScore4h": 0,
      "trendingScore6h": 0,
      "trendingScore12h": 0,
      "trendingScore24h": 0,
      "isMayhemMode": null,
      "isCashbackCoin": null,
      "isAgentMode": null,
      "top10HoldingsPercentage": 123,
      "top50HoldingsPercentage": 123,
      "top100HoldingsPercentage": 123,
      "top200HoldingsPercentage": 123,
      "devHoldingsPercentage": 123,
      "insidersHoldingsPercentage": 123,
      "bundlersHoldingsPercentage": 123,
      "snipersHoldingsPercentage": 123,
      "proTradersHoldingsPercentage": 123,
      "freshTradersHoldingsPercentage": 123,
      "smartTradersHoldingsPercentage": 123,
      "insidersCount": 123,
      "bundlersCount": 123,
      "snipersCount": 123,
      "freshTradersCount": 123,
      "proTradersCount": 123,
      "smartTradersCount": 123,
      "freshTradersBuys": 123,
      "proTradersBuys": 123,
      "smartTradersBuys": 123
    }
  ]
}
This endpoint is available for all plans.

POST Method Overview

POST /api/2/fast-search accepts the same payload shape as a single pulse v2 view, plus one extra field — input — that carries the search term. Any filters block you can send to POST /api/2/pulse is a valid filters block here. Use POST when you need:
  • AND / OR / NOT logic (e.g. per-chain conditional constraints).
  • Rich Prisma operators (gte, lte, in, notIn, contains, startsWith, endsWith, mode: "insensitive").
  • A structured JSON body instead of URL-encoded query strings.

Base Endpoint

https://api.mobula.io

Endpoint

POST /api/2/fast-search

Body Shape

{
  input: string;                       // search term (name / symbol / address)
  chainId?: string | string[];         // optional — same as pulse `view.chainId`
  poolTypes?: string | string[];       // optional — same as pulse `view.poolTypes`
  sortBy?: string;                     // default: "volume_24h"
  sortOrder?: "asc" | "desc";          // default: "desc"
  limit?: number;                      // 1–20, default 5
  offset?: number;                     // default 0
  filters?: Record<string, unknown>;   // Prisma-like AND/OR/NOT tree
}

input

The search term. Prefix match on tokenName / tokenSymbol / asset_name / asset_symbol, or exact address match if the value is a valid address > 26 chars. Wrap in double quotes for Google-style exact-symbol match (e.g. "W" matches only tokens with symbol “W”).

chainId (optional)

Single chainId or array. Mirrors pulse view.chainId. Translated to chainId: { in: [...] } and ANDed with filters. When you need per-chain conditional logic (e.g. different constraints per chain), skip this field and express the chain constraint inside filters using OR.

poolTypes (optional)

Single poolType or array. Mirrors pulse view.poolTypes. Translated to source: { in: [...] }.

sortBy / sortOrder

Accepts both camelCase (volume24h, feesPaid24h, …) and snake_case (volume_24h, fees_paid_24h, …) — same list as the GET variant. Default volume_24h desc.
sortBy: "searchScore" is GET-only (derived ranking that isn’t part of the Prisma model). On POST it falls back to volume_24h. Use GET when you need searchScore ranking.

filters

A Prisma-like where tree — identical syntax to pulse view.filters. Supported operators:
  • Logical: AND, OR, NOT
  • Comparison: equals, not, gte, gt, lte, lt, in, notIn
  • String: contains, startsWith, endsWith, with mode: "insensitive"
Field names are the Prisma model fields of TokensStatsRealTime, same as pulse — chainId, tokenName, tokenSymbol, volume_24h, volume_1h, fees_paid_24h, fees_to_volume_ratio_24h, totalFeesPaidUSD, holders_count, bonded, bonded_at, shadow_ban, bundlers_holdings_percentage, dev_holdings_percentage, source, factory, deployer, market_cap, created_at, trending_score_24h, etc.

🔍 Complete Filter Reference

The pulse stream docs list every filterable field — they apply 1:1 here.

Examples

Example 1 — Basic: chain scope + min 24h volume

curl -X POST 'https://api.mobula.io/api/2/fast-search' \
  -H 'Content-Type: application/json' \
  -d '{
    "input": "doge",
    "chainId": ["evm:1", "evm:56", "solana:solana"],
    "sortBy": "volume24h",
    "limit": 10,
    "filters": {
      "volume_24h": { "gte": 10000 }
    }
  }'
Top-level chainId is the simplest way to restrict to a few chains — same shorthand as pulse view.chainId.

Example 2 — AND / NOT: high-liquidity tokens, exclude shadow-banned

curl -X POST 'https://api.mobula.io/api/2/fast-search' \
  -H 'Content-Type: application/json' \
  -d '{
    "input": "pepe",
    "sortBy": "feesPaid24h",
    "limit": 10,
    "filters": {
      "AND": [
        { "volume_24h": { "gte": 50000 } },
        { "holders_count": { "gte": 500 } },
        { "NOT": { "shadow_ban": true } }
      ]
    }
  }'

Example 3 — OR per-chain: Solana requires a min fees-to-volume ratio, EVM doesn’t

Use case: on Solana you want tokens that generate real fee revenue relative to their volume (filters out wash-traded tokens); on EVM chains fee-tracking is less reliable so you don’t want that constraint to exclude legitimate results. Because chainId is expressed inside the tree, the constraint applies per OR branch — exactly what the top-level chainId shorthand cannot do.
curl -X POST 'https://api.mobula.io/api/2/fast-search' \
  -H 'Content-Type: application/json' \
  -d '{
    "input": "cat",
    "sortBy": "volume24h",
    "limit": 10,
    "filters": {
      "OR": [
        {
          "AND": [
            { "chainId": "solana:solana" },
            { "fees_to_volume_ratio_24h": { "gte": 0.002 } }
          ]
        },
        { "chainId": { "startsWith": "evm:" } }
      ]
    }
  }'
The exact same filters block pasted under a pulse view’s filters field works identically — fast-search POST and pulse POST share the same filter surface.

GET vs POST

Use POST when:

  • You need AND/OR/NOT logic.
  • You need per-chain conditional constraints.
  • You want a structured JSON body instead of URL-encoded query strings.
  • You want the searchScore-independent Prisma orderBy (all other sort fields work).

Use GET when:

  • Your filter is a flat set of constraints (chain list + min/max on a few numeric fields).
  • You want searchScore ranking (the composite fees_paid_24h × largest_pool_reserve_usd rank).
  • Your client can’t easily POST JSON (simple scripting / shell).

🔗 GET Method

Simple search with URL-encoded filters query string.

📡 Pulse POST

Same filter surface, but returning live pool/token views rather than search hits.

Body

application/json
input
string
required

Search query string

chainId

Chain ID(s) to filter — same shorthand as pulse view.chainId

poolTypes

Pool type(s) to filter — same shorthand as pulse view.poolTypes

filters
object

Prisma-like where tree (AND/OR/NOT + leaf operators equals, not, gte, gt, lte, lt, in, notIn, contains, startsWith, endsWith). Same surface as view.filters on POST /2/pulse.

sortBy
enum<string>

Sort field for search results (default: volume24h; searchScore falls back to volume_24h on POST)

Available options:
volume24h,
marketCap,
createdAt,
volume1h,
feesPaid5min,
feesPaid1h,
feesPaid24h,
volume5min,
holdersCount,
organicVolume1h,
totalFeesPaidUsd,
searchScore,
trendingScore24h
sortOrder
enum<string>

Sort order (default: desc)

Available options:
asc,
desc
limit
number

Maximum number of results (1-20, default: 5)

offset
number

Offset for pagination (default: 0)

Response

200 - application/json

Universal Search response

data
object[]
required