Build a Polymarket Whale-Alert Bot in Python
Whale wallets on Polymarket are public on-chain, but watching them by hand is hopeless — positions shift while you sleep. This tutorial builds a small Python bot that polls for large wallet moves and pings you on Telegram when a new one shows up. It runs on the free tier, and the whole thing is under 60 lines.
We'll use the Apify actor apimie/polymarket-whales-tracker as the data layer, so there's no scraper to maintain and no on-chain indexing to set up.
What you'll need
- •Python 3.10+
- •An Apify token — the actor is the entry point; grab a token from your Apify account.
- •An apimie account — sign up free. Your tier sets the limits (calls per day, lookback, refresh); the free tier is enough to follow along.
- •A Telegram bot — message @BotFather, run
/newbot, and save the token it gives you. Send your bot a message, then read yourchat_idfromhttps://api.telegram.org/bot<TOKEN>/getUpdates.
pip install requests
Step 1 — Pull the current whale list
The whale_list action returns active whale wallets sorted by volume. One POST to the actor and you get JSON back:
curl -s -X POST \
"https://api.apify.com/v2/acts/N5u8wVgS1bKzibZdf/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"action":"whale_list","limit":100}'
Each record is one wallet:
{
"proxy_wallet": "0x84cfffc3...",
"total_volume_usdc": "259659.67",
"buy_volume_usdc": "259659.67",
"sell_volume_usdc": "0.00",
"total_trades": 2170,
"last_movement_at": "2026-05-29T10:26:10.000Z"
}
A wallet with sell_volume_usdc: 0 has never sold — it's a pure buyer, which is the strongest directional signal in the set.
Here's the same call in Python:
import requests
APIFY_TOKEN = "your_apify_token_here"
ACTOR = "N5u8wVgS1bKzibZdf"
def get_whales(limit=100):
r = requests.post(
f"https://api.apify.com/v2/acts/{ACTOR}/run-sync-get-dataset-items",
params={"token": APIFY_TOKEN},
json={"action": "whale_list", "limit": limit},
timeout=120,
)
r.raise_for_status()
return r.json()
Step 2 — Detect what's actually new
Every poll returns the full list, so you need to remember what you've already seen — otherwise you'll alert on the same wallets forever. Key each move by wallet and its last-movement timestamp: when a wallet trades again, the timestamp changes and it counts as new.
def move_id(w):
return (w["proxy_wallet"], w["last_movement_at"])
Keep the seen IDs in a set. On the first run, mark everything as seen without alerting, so you don't get blasted with the entire current list on startup.
Step 3 — Send the alert
Plain Telegram Bot API, no SDK:
TG_TOKEN = "your_telegram_bot_token"
TG_CHAT_ID = "your_chat_id"
def alert(text):
requests.post(
f"https://api.telegram.org/bot{TG_TOKEN}/sendMessage",
json={"chat_id": TG_CHAT_ID, "text": text, "parse_mode": "Markdown"},
timeout=30,
)
Step 4 — Poll on a sane interval
Don't poll faster than the data refreshes — you'd just burn calls re-reading the same snapshot. Snapshots refresh as often as every 15 minutes on the top tier; the free tier's quota is small and shared with chat, so a longer interval is the right call while you test. Match your loop to your tier.
import time
POLL_SECONDS = 900 # top tier refreshes every 15 min; raise this on free
MIN_VOLUME = 10_000 # only alert on wallets above $10k
def run():
seen = set()
first_pass = True
while True:
try:
for w in get_whales():
mid = move_id(w)
if mid in seen:
continue
seen.add(mid)
vol = float(w["total_volume_usdc"])
if first_pass or vol < MIN_VOLUME:
continue
side = "pure buyer" if float(w["sell_volume_usdc"]) == 0 else "mixed"
alert(
f"🐋 *Whale move*\n"
f"`{w['proxy_wallet']}`\n"
f"Volume: ${vol:,.0f} · {w['total_trades']} trades · {side}"
)
first_pass = False
except requests.RequestException as e:
print(f"poll failed: {e}")
time.sleep(POLL_SECONDS)
if __name__ == "__main__":
run()
That's the whole bot. Run it with python bot.py and leave it on a small VPS, a Raspberry Pi, or a free-tier container — anything that stays awake.
Where to take it next
- •Per-market alerts — swap
whale_listformarket_whalesto watch whales on one specific market instead of the whole board. - •Pure-buyer filter — only alert when
sell_volume_usdcis 0 andtotal_volume_usdcclears a higher bar. Fewer pings, stronger signal. - •Per-market PnL — call
market_whalesto see each whale'soutcome_name,net_size_usdc,avg_entry_pricevscurrent_price, andunrealized_pnl. Follow the wallets that are actually in profit. - •Persist state — write
seento a file or Redis so a restart doesn't replay the current list.
A whale move isn't a trade signal on its own — a large position can be a hedge, and any wallet can be wrong. Treat it as one input among several, not a green light.
If you want the data layer without standing up your own scraper, that's what apimie is — see the API. The free tier is enough to get this bot running today.