Step-by-step guide to building a Solana token screener with Birdeye Data: trending feed discovery, bulk scanning 5,000 tokens per call with 40+ filters, and CU-optimized watchlist refresh.
July 3, 2026
Most token screeners fail at scale not because of the UI, but because of how they fetch data. They poll everything, enrich everything, and run into rate limits before they even reach 50 concurrent users.
This guide builds the token screener pipeline differently, using Birdeye Data: a multi-chain market data layer covering real-time prices, liquidity, trade activity, and holder stats across Solana and major EVM networks. The entire token screener runs on 4 endpoints.
The pipeline is built around one rule: only enrich tokens that survive the Discover and Filter stages. Token Overview calls are the most data-rich in the stack. Wasting them on tokens nobody selects is how you burn CU budget without delivering value.

To build a token screener on Solana or EVM with Birdeye Data, you need 4 endpoints covering discovery, filtering, enrichment, and watchlist refresh.
GET /defi/token_trending to pull a pre-ranked list of trending tokens by volume or liquidity across 1h, 4h, or 24h windows.GET /defi/v3/token/list/scroll to bulk-scan up to 5,000 tokens per batch using 40+ server-side filters (market cap, FDV, holders, volume, price momentum).GET /defi/token_overview on demand when a user selects a token, to get a full single-token snapshot: price, liquidity, unique wallets, buy/sell volume, and more.POST /defi/multi_price to refresh price and liquidity for up to 100 watchlist tokens in one request.The pipeline starts with discovery because you need a ranked, filtered universe before you do anything else. Polling every token on-chain from scratch is not viable. The trending feed gives you a pre-qualified starting point in one call.
All endpoints share the same base URL (https://public-api.birdeye.so), use X-API-KEY for auth, and select the network via the x-chain header (e.g. solana, ethereum, base, bsc, arbitrum, polygon). Note that Stage 2 uses a scroll endpoint available on Business and Enterprise plans. If you are on a lower plan, there is a fallback covered at the end of that section.
Endpoint: GET /defi/token_trending
Chains: All supported networks
Docs: Token – Trending List
Computing “what’s trending” yourself from raw trade data is a rabbit hole. This endpoint skips all of that. Birdeye already derives a pre-ranked list from real on-chain activity, and you just call it. You control the sort field (rank, volumeUSD, or liquidity) and the lookback window (1h, 4h, or 24h).
Key parameters:
| Parameter | Required | Notes |
|---|---|---|
sort_by | Yes | rank, volumeUSD, or liquidity |
sort_type | Yes | asc or desc |
interval | No | 1h, 4h, 24h (default 24h) |
limit | No | 1–50 per page (default 50) |
offset | No | Pagination cursor (default 0) |
x-chain (header) | No | Network selector, default solana |
curl --request GET \\
--url '<https://public-api.birdeye.so/defi/token_trending?sort_by=rank&sort_type=asc&interval=1h&offset=0&limit=50>' \\
--header 'X-API-KEY: YOUR_API_KEY' \\
--header 'x-chain: solana' \\
--header 'accept: application/json'
The response already includes everything you need to render a trending table without any follow-up calls: address, symbol, name, logoURI, rank, price, price24hChangePercent, liquidity, volume24hUSD, volume24hChangePercent, fdv, and marketcap.

A few things worth knowing before you wire this up: the page size hard-caps at 50 tokens, so paginate with offset if you need a deeper board. For a meme terminal or sniper bot where momentum matters more than volume, interval=1h surfaces breakout tokens much earlier than 24h. And since chain selection is just a header swap, you can serve the same trending feed on Ethereum, Base, BSC, and Arbitrum with zero extra code.
Now you have a short, pre-ranked list. The next step is cutting it down further using server-side filters before you touch a single token in detail.
Endpoint: GET /defi/v3/token/list/scroll
Chains: Solana, Base, BSC, Ethereum
Plan availability: Business and Enterprise packages
Docs: Token – List (V3) Scroll
This is where the token screener’s CU efficiency is actually built. Instead of downloading a massive token list and filtering client-side, you push all filter logic to the server and get back only tokens that match. Up to 5,000 tokens per batch, with 40+ filter parameters covering:
min_liquidity, max_liquiditymin_market_cap, max_market_cap, min_fdv, max_fdvmin_holdermin_recent_listing_time, max_recent_listing_time (unix timestamp)min_last_trade_unix_time, max_last_trade_unix_timemin_volume_{1m,5m,30m,1h,2h,4h,8h,24h,7d,30d}_usd and matching _change_percent filtersmin_price_change_{1m…30d}_percentmin_trade_{1m…30d}_countOne thing that trips people up: both sort_by and sort_type are required params, not optional. sort_by accepts liquidity, market_cap, fdv, holder, recent_listing_time, or any of the volume/price-change/trade-count fields. Forget either one and you’ll get a 400.
A practical “tradeable small caps” scan on Solana:
# Initial request — no scroll_id
curl --request GET \\
--url '<https://public-api.birdeye.so/defi/v3/token/list/scroll?sort_by=volume_24h_usd&sort_type=desc&min_liquidity=50000&min_holder=500&min_volume_24h_usd=100000&min_trade_24h_count=1000&limit=5000>' \\
--header 'X-API-KEY: YOUR_API_KEY' \\
--header 'x-chain: solana'
scroll_id: read this before you shipThe scroll session model is not the same as standard offset pagination, and getting it wrong is a common cause of production bugs.
On your initial request, omit scroll_id entirely and send your filters normally. The response includes a next_scroll_id. On every subsequent page, send only scroll_id with that value and drop all filter params. The session already holds your query context server-side, so if you re-send filters on a paginated request, the API ignores them.
The harder constraint: only one active scroll_id is allowed per account at any given time, with a 30-second cooldown. A scroll_id also expires if 30 seconds pass without a follow-up request, or if items comes back empty (which signals end of results). Either way, start a fresh session from the initial request.
# Follow-up page — scroll_id only
curl --request GET \\
--url '<https://public-api.birdeye.so/defi/v3/token/list/scroll?scroll_id=NEXT_SCROLL_ID_FROM_PREVIOUS_RESPONSE>' \\
--header 'X-API-KEY: YOUR_API_KEY' \\
--header 'x-chain: solana'
This one session per account constraint has a direct architectural implication: the bulk scan needs to run as a single background worker writing into a cache or database. Your token screener UI reads from that cache. It never hits the scroll endpoint directly per user request. If you skip this separation and let multiple concurrent users trigger scroll sessions, you will hit 400 errors immediately.
The response per item is already dense: price, liquidity, market_cap, fdv, holder, multi-window volume_*_usd, price_change_*_percent, trade_*_count, and recent_listing_time. Your token screener table can render entirely from the cache without any per-token follow-up calls.
Note on availability: the scroll endpoint requires a Business or Enterprise package and currently covers Solana, Base, BSC, and Ethereum. On other plans, GET /defi/v3/token/list exposes the same filter and sort parameters with standard offset/limit pagination at up to 100 tokens per call. The same funnel logic applies, just with smaller pages.
At this point your cache holds a filtered, ranked list of tokens worth watching. Stage 3 only runs when a user actually picks one.
Endpoint: GET /defi/token_overview
Chains: All supported networks
Docs: Token – Overview
When a user selects a token in your screener, this is the one call you make. It returns price, liquidity, marketCap, fdv, holder count, totalSupply/circulatingSupply, numberMarkets, project metadata (website, Twitter, Discord via extensions), and a full suite of per-timeframe metrics: price change, unique wallets, trade counts, and buy/sell volume in USD across eight windows by default (1m, 5m, 30m, 1h, 2h, 4h, 8h, 24h).
curl --request GET \\
--url '<https://public-api.birdeye.so/defi/token_overview?address=So11111111111111111111111111111111111111112>' \\
--header 'X-API-KEY: YOUR_API_KEY' \\
--header 'x-chain: solana'
If your token detail view only needs a subset of timeframes, the frames parameter is worth using. You can request up to 8 custom intervals in a single call: minute granularity from 1m to 1440m, second granularity in multiples of 5s up to 3600s, and fixed hour intervals (1h, 2h, 4h, 8h, 24h). Narrowing frames reduces response payload size, which matters at scale. If you’re building on other chains, keep in mind that second and minute interval granularity only works on Solana, Base, BSC, and Ethereum for now. On other chains, stick to the standard hour intervals.
This is where the CU optimization pays off. token_overview is the heaviest call in the stack. If your funnel is working correctly, it only fires when a real user clicks a pre-qualified token, not speculatively on every scan result.
Endpoint: POST /defi/multi_price
Chains: All supported networks
Docs: Price – Multiple
Once users build watchlists, you need a refresh loop that doesn’t scale linearly with watchlist size. multi_price handles up to 100 tokens in a single POST, returning value (USD price), priceChange24h, and updateUnixTime per token. Add include_liquidity=true to the query string to get current liquidity as well. On Solana, priceInNative (price in SOL) is also included.
curl --request POST \\
--url '<https://public-api.birdeye.so/defi/multi_price?include_liquidity=true>' \\
--header 'X-API-KEY: YOUR_API_KEY' \\
--header 'x-chain: solana' \\
--header 'content-type: application/json' \\
--data '{
"list_address": "So11111111111111111111111111111111111111112,DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"
}'
A few gotchas worth handling explicitly in your code:
list_address as a comma-separated string in the request body (required). Max 100 per call.null on their key, not as an error. If you don’t guard against this, you’ll get null pointer exceptions when iterating results.check_liquidity param lets you filter out prices from pools with insufficient liquidity, useful if you’re using this for trade signals rather than just display.One watchlist of 100 tokens equals one HTTP request per refresh tick. Batching through multi_price instead of looping single-price calls cuts 100 requests down to 1, and that’s the difference between a screener that holds up under load and one that doesn’t.
With the pipeline running, you need one more thing: visibility into how much CU budget all four stages are actually consuming.
Endpoint: GET /utils/v1/credits
Docs: Utils – Credits Usage
Wire this into your monitoring stack from day one. Without visibility into CU consumption, you won’t know whether the token screener is behaving as designed or silently burning budget on an edge case.
curl --request GET \\
--url '<https://public-api.birdeye.so/utils/v1/credits>' \\
--header 'X-API-KEY: YOUR_API_KEY'
With no parameters it returns the current billing cycle: total usage broken down into REST api and WebSocket ws, remaining credits, and overage_usage/overage_cost. You can also pass time_from/time_to as unix timestamps to query up to one year back, though remaining and overage fields return null for historical windows outside the current cycle.
A practical pattern: poll this hourly and alert if remaining credits drop below a safe threshold. If they do, automatically increase your refresh interval or pause the background scan worker rather than letting it run into a 429.
Here is how all four stages connect into a single deployable architecture.

The background worker runs the Discover and Filter stages on a cron schedule, writing results to a shared cache. The user-facing app reads exclusively from that cache for the screener table, then fires a single token_overview call only when a user selects a specific token. Watchlist refreshes batch up to 100 tokens per multi_price call on a fixed tick. CU usage is monitored hourly to catch runaway consumption before it hits overage.
Code review checklist before you ship your token screener:
token_overview fires only on explicit user selection, never speculatively.multi_price and never loops single-price calls.null responses from multi_price are handled explicitly, not assumed away.No. Unlike most other Birdeye Data endpoints that support all networks, GET /defi/v3/token/list/scroll currently only covers Solana, Base, BSC, and Ethereum. If you’re building a token screener on other chains, use GET /defi/v3/token/list instead. It has the same filter and sort parameters, just with standard offset/limit pagination at up to 100 tokens per call.
Not with the scroll endpoint. The one active scroll ID per account constraint is enforced at the account level, not the key level. If two workers try to open concurrent scroll sessions, the second one will fail. The correct pattern is one worker per chain per account, writing to a shared cache that all application instances read from.
null responses from multi_price?Iterate the response as a map and explicitly check each token key before accessing fields. A null value means the token is not indexed or not supported on the requested chain. It is not an error state, so the API returns 200 with null on that key rather than a 4xx. If your downstream logic (e.g. trade signal calculation) requires a valid price, skip or flag that token rather than letting it propagate as an undefined value.
token_overview response is large. Can I reduce it?Yes, use the frames parameter to request only the timeframes your UI actually displays. If your token detail page shows 1h, 4h, and 24h only, send frames=1h,4h,24h and you’ll get a much smaller payload. The default response returns all eight standard windows whether you need them or not.
It depends on your use case, but a reasonable starting point for a trading terminal is 5 to 10 seconds per batch via multi_price. Monitor your CU consumption via GET /utils/v1/credits and tune from there. Avoid refreshing tokens that are not visible in the current viewport.
Explore the full endpoint catalog in the Birdeye Data API reference or compare data packages at birdeye.so/data-api.
Birdeye Data is a high-performance data provider that delivers real-time, accurate, and comprehensive on-chain data across tokens, wallets, trades, and protocols on Solana, Sui and major EVM chains. From fast-moving startups to global leaders like Phantom, Raydium, Coinbase, and Bybit, Birdeye Data powers teams of all sizes with the data they need to build and scale confidently.
Stay connected with us: Website | X | Docs | Blog | Telegram
Birdeye provides expansive data covering tokens, wallets, trades, and protocols across 300+ exchanges on 10 chains.
Whether you’re a solo tinkerer or a large team looking to scale, Birdeye offers plans that caters for your data needs and budget.
Dive into our docs and start querying data on 60+ APIs and 8 WebSocket types today!
Insights is a feature that allows users to analyze market trends in various aspects and dive deep into many industry sectors.
Find Gems is a feature that helps user identify potential Tokens at the current time.
Launch Explorer is a feature that enables users to access real-time data of tokens on popular launchpads like pump.fun, letsbonk.fun,...
New insight article by Birdeye reveals USDC's breakout growth in recent years
Data by Birdeye shows total trading volume of xStocks, PreStocks, and Ondo Global Markets on Solana peaked in March 2026
After the Drift Protocol's hack, Solana Foundation initiated programs such as STRIDE and SIRIN to tighten security for ecosystem teams
July 3, 2026
July 3, 2026
July 3, 2026