TL;DR
- Poll the whole watchlist in one cheap batch call
- Drill into exact thresholds only for tokens near a level
- Confirm the move on a closed candle before firing
All requests share the base URL https://public-api.birdeye.so, authenticate with the X-API-KEY header, and select the network with the x-chain header, defaulting to solana.
This design runs entirely over REST polling. Birdeye Data offers a WebSocket price feed, but on the Premium tier it sits behind a Business upgrade, so tiered polling, a cheap batch scan plus targeted drill downs, keeps cost low without needing the socket.
The three stage loop
1
Poll the watchlist in one call
You do not want a separate request per token when a watchlist can run to dozens of names. One batch call keeps every loop cheap.Endpoint:
GET /defi/multi_price2
Check absolute and percent thresholds
When a token from the poll looks close to a level, drill in for the exact numbers that decide whether to fire.Endpoint:
GET /defi/v3/price/stats/single3
Confirm the move on a closed candle
A threshold check on a live price fires on wicks, brief spikes that snap back within the same candle. Confirming on a closed candle removes them, and the same call doubles as a custom baseline.Endpoint:
GET /defi/v3/ohlcvChoose your alert types
Three alert types cover almost every case, and each maps to one call above:- Absolute price alert: fires on a fixed price target. Read
pricefrom the stats call, orvaluefrom the batch poll. The cheapest alert, since the batch poll alone can drive it. - Percent move alert: fires on a relative change over a window. Read
price_change_percentfor that timeframe, precomputed so you never store a prior price yourself. - Custom baseline alert: fires on a move since a reference point the fixed windows do not cover. Point
time_fromon the candle call at that moment.
Debounce is what separates a usable monitor from an unusable one. A token sitting above a threshold trips it on every loop, so track an alert state per token, fire once on the crossing, and reset only when the price falls back through the level.
Watch your credit budget
A monitor runs forever, so its cost compounds. A watchlist of 100 tokens polled once a minute is 1,440 batch calls a day before any drill down calls stack on top. Endpoint:GET /utils/v1/credits
Survive the gaps in a polling loop
A monitor that only works when every request succeeds will not survive its first bad night.- Retry transient failures. One missed poll is normal, several in a row means a token could cross a threshold and cross back before you notice. Retry with a short backoff and log the gap rather than pretending the loop ran clean.
- Guard against stale prices. The batch response carries
updateUnixTimeper token. A thinly traded token can hand back a price minutes old. Compare it against the current time and skip any token older than your alert window. - Persist debounce state. If the alert state only lives in memory, a restart wipes it, and every token already above threshold fires all over again. Persist state next to the watchlist and treat the first loop after a restart as a rebuild, not a normal pass.
- Keep the host clock synced. Every candle boundary and custom baseline comes down to a Unix timestamp comparison, so a drifting clock asks for a candle that has not closed yet.
Before you ship
- The batch poll reads
value, notprice, and splits watchlists longer than 100 into batches. - The stats call reads snake_case
price_change_percentfrom the nesteddataarray. - The candle confirmation reads the last closed candle, checked by
unix_time, not the forming one. - Every alert is debounced by per token state so it fires once per crossing.
updateUnixTimeis checked before trusting a price as fresh.- Debounce state is persisted so a restart does not refire every open alert.
FAQ
Why poll over REST instead of using a WebSocket?
Why poll over REST instead of using a WebSocket?
Birdeye Data offers a WebSocket price feed, but on the Premium tier it sits behind a Business upgrade. Tiered polling, a cheap batch scan plus targeted drill downs, keeps cost low enough that the socket is not needed for most watchlists.
How do you avoid false alerts?
How do you avoid false alerts?
Every threshold break is confirmed on a closed candle. A live price can spike and revert within a single candle, so the monitor reads the close of the last completed candle and fires only if that confirmed value clears the threshold.
How do you stop the same alert firing repeatedly?
How do you stop the same alert firing repeatedly?
Track an alert state per token. Fire once when the price crosses the level, mark the token alerted, and clear that state only when the price falls back through the level.

