Polymarket strategies and research
28 studies on the recorded Polymarket data, each a question with its answer, the Python that gets it and the sentence to ask your AI agent instead. Every one was run against the live API on 2026-11-03.
“How often does Up win on 5-minute BTC markets, by hour of the day?”
polymarket_settlements_bulk“Which Polymarket wallets farm a high hit rate on tiny profits?”
polymarket_leaderboardAll 28 questions
Jump to any study; ● marks the ones with a finding measured on 2026-11-03.
How accurate is Polymarket?
5- and 15-minute crypto markets
- How often does Up win on 5-minute BTC markets, by hour of day? (measured finding)
- Do Up and Down shares ever cost less than $1 together on 5-minute BTC markets?
- How long after a 5-minute window closes does the market resolve on-chain? (measured finding)
- Compare the order book of Polymarket's 5-minute and 15-minute crypto Up/Down markets, coin by coin
- Walk every settled 5-minute BTC market in one script
Order book, spread and backtests
- Backtest a Polymarket strategy on the real historical book (fills, fees, lookahead)
- Slippage: what would a $X order have cost at time T?
- Polymarket bid-ask spread and depth history
- What does Polymarket liquidity look like in the final seconds before a market closes?
- Polymarket order book at a past moment
- Rebuild the Polymarket order book tick by tick from book events
- Label every book event in an archive day with its market's outcome
Traders and smart money
- Where is Polymarket smart money flowing? Mispriced markets
- Which Polymarket wallets are farmers: a high hit rate on a sliver of profit? (measured finding)
- Market maker or bettor? Classify a Polymarket trader
- Polymarket trader profile: realized PnL 24h/7d/30d/all, hit rate, categories
- Polymarket leaderboard by realized PnL and hit rate, per category
- Is this Polymarket wallet's profit real? Check realized PnL against on-chain settlements
Markets and trades
- Find a Polymarket market by slug, condition_id or token_id; event URL → token ids
- How did this Polymarket market resolve?
- List every Polymarket market that resolved in the last 24 hours and which side won
- Every trade of a Polymarket market in the last 30 days
- Buy versus sell pressure and Yes versus No volume of a Polymarket market, by hour
- Tape summary of a Polymarket outcome token (events, first and last recorded)
How accurate is Polymarket?
Prices and odds against what actually happened.
How accurate were Polymarket's final prices? A calibration curve
Bucket Polymarket prices taken a fixed time before each market closes and compare each bucket with how often that outcome won.
- Uses
/archive/datasets,/ohlcv,/settlements,/settlements/bulk- Verified
- live API, 2026-11-03: 6 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# Up's minute bars from two minutes before the window end to the final minute
r = requests.get(
"https://data.vike.io/v1/polymarket/ohlcv?token_id=49453782677730298729295238194951727156421227964664364260179136470131299796336&interval=1m&from=1792840380000&to=1792840440000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# settled 5-minute BTC markets, with token ids and the winner
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792840425357&limit=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the Yes token's daily bar that starts seven to eight days before resolution
r = requests.get(
"https://data.vike.io/v1/polymarket/ohlcv?token_id=100208760979006815700821365554623989048585541964271047036444923380678560443951&interval=1d&from=1787721750000&to=1787808150000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the on-chain winner of the same market
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/0x69e0442186b71c5cac4fa6304311e39101ed048983a200fc8e376a9dadd7de13",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# Up's first minute bar of the window
r = requests.get(
"https://data.vike.io/v1/polymarket/ohlcv?token_id=49453782677730298729295238194951727156421227964664364260179136470131299796336&interval=1m&from=1792840200000&to=1792840200000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the daily trades files of the 5-minute BTC family
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/datasets?asset=btc&tenor=5m&stream=trades&limit=5",
headers={"X-API-Key": API_KEY},
)
Polymarket BTC Up/Down odds vs the BTC price
Pull the Up token's minute bars for one 5-minute window from /polymarket/ohlcv and BTC's minute bars for the same window from /hyperliquid/ohlcv, and line them up by ts.
- Uses
/ohlcv,/settlements/bulk- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# Up's probability, minute by minute, for the 7:10-7:15 AM ET window of 2026-10-24
r = requests.get(
"https://data.vike.io/v1/polymarket/ohlcv?token_id=49453782677730298729295238194951727156421227964664364260179136470131299796336&interval=1m&from=1792840200000&to=1792840499999",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# BTC perp minute bars for the same five minutes (end is exclusive here)
r = requests.get(
"https://data.vike.io/v1/hyperliquid/ohlcv?symbol=BTC&interval=1m&start=1792840200000&end=1792840500000&limit=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the settled 5-minute BTC markets of the same hours, with the winning outcome
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792840425357&limit=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# ETH perp minute bars for the same window
r = requests.get(
"https://data.vike.io/v1/hyperliquid/ohlcv?symbol=ETH&interval=1m&start=1792840200000&end=1792840500000&limit=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# Down's minute bars for the same window
r = requests.get(
"https://data.vike.io/v1/polymarket/ohlcv?token_id=47308938681852370891240392538597346060423878069086601789592769907537520980452&interval=1m&from=1792840200000&to=1792840499999",
headers={"X-API-Key": API_KEY},
)
Polymarket odds history: OHLCV candles of an outcome
One outcome token's candles, oldest first, priced as a probability from 0 to 1, at 1m, 5m, 1h or 1d, from /ohlcv?token_id=&interval=1h.
- Uses
/markets,/ohlcv- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# hourly odds of Yes on "Will Kylian Mbappe finish in the top 3 of the 2026 Ballon d'Or?", from three days ago
r = requests.get(
"https://data.vike.io/v1/polymarket/ohlcv?token_id=74473996442012992380676870006739770237037057336567567233855106290930440805273&interval=1h&from=1792602825357&limit=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# daily bars from the start of the token's tape
r = requests.get(
"https://data.vike.io/v1/polymarket/ohlcv?token_id=74473996442012992380676870006739770237037057336567567233855106290930440805273&interval=1d&limit=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# hourly odds of No on the same market
r = requests.get(
"https://data.vike.io/v1/polymarket/ohlcv?token_id=94460938716696962400906318004981079238211572891965687608128793145682575549865&interval=1h&from=1792602825357&limit=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# 2026-10-23 in 5-minute bars
r = requests.get(
"https://data.vike.io/v1/polymarket/ohlcv?token_id=74473996442012992380676870006739770237037057336567567233855106290930440805273&interval=5m&from=1792713600000&to=1792799999999&limit=288",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the market's two token ids, Yes first
r = requests.get(
"https://data.vike.io/v1/polymarket/markets?query=will-kylian-mbappe-finish-in-the-top-3-of-the-2026-ballon-dor&limit=1",
headers={"X-API-Key": API_KEY},
)
# then: jq '.[0].token_ids'
What is the price of every outcome in a multi-outcome Polymarket event?
List the event's markets with /markets?query=<shared slug words>&active=true, then read the top of book of each market's Yes token with /orderbook?depth=1.
- Uses
/markets,/ohlcv,/orderbook- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the open markets of one event, found by the words their slugs share
r = requests.get(
"https://data.vike.io/v1/polymarket/markets?query=win-the-2028-us-presidential-election&active=true&limit=100",
headers={"X-API-Key": API_KEY},
)
for m in r.json():
print(m["slug"], m["token_ids"][0]) # token_ids[0] is the Yes token
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# once per market: the best bid and ask of its Yes token (token_ids[0]); here JD Vance
r = requests.get(
"https://data.vike.io/v1/polymarket/orderbook?token_id=16040015440196279900485035793550429453516625694844857319147506590755961451627&depth=1",
headers={"X-API-Key": API_KEY},
)
print(r.json())
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# every market of the event, the closed outcomes too: leave active=true out
r = requests.get(
"https://data.vike.io/v1/polymarket/markets?query=win-the-2028-us-presidential-election&limit=100",
headers={"X-API-Key": API_KEY},
)
print(len(r.json()), "markets")
import os
import time
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# hourly bars of one Yes token since a day ago; the last row's close is the latest traded probability
day_ago = int(time.time() * 1000) - 86_400_000
r = requests.get(
f"https://data.vike.io/v1/polymarket/ohlcv?token_id=16040015440196279900485035793550429453516625694844857319147506590755961451627&interval=1h&from={day_ago}",
headers={"X-API-Key": API_KEY},
)
print(r.json()[-1:])
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the top of book with repeated rows removed: the same (side, level) can come back more than once
r = requests.get(
"https://data.vike.io/v1/polymarket/orderbook?token_id=16040015440196279900485035793550429453516625694844857319147506590755961451627&depth=1",
headers={"X-API-Key": API_KEY},
)
print(list({(row["side"], row["level"]): row for row in r.json()}.values()))
5- and 15-minute crypto markets
Up/Down markets: who wins, when, and how fast they settle.
How often does Up win on 5-minute BTC markets, by hour of day?
Up's win rate on Polymarket 5-minute BTC markets by UTC hour of day, from two weeks of settled markets in one call.
- Uses
/settlements/bulk- Verified
- live API, 2026-11-03: 4 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# two weeks of settled 5-minute BTC markets, Up's share of wins per UTC hour of the window start
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1791652883201&limit=5000",
headers={"X-API-Key": API_KEY},
)
# then: jq '.settlements | map(select(.winning_outcome != "")) | group_by(.slug | ltrimstr("btc-updown-5m-") | tonumber % 86400 / 3600 | floor) | map({utc_hour: (.[0].slug | ltrimstr("btc-updown-5m-") | tonumber % 86400 / 3600 | floor), markets: length, up_share: ((map(select(.winning_outcome == "Up")) | length) / length * 1000 | round / 1000)})'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# page 1 of every settled 5-minute BTC market
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&limit=5000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# Up's share of wins per UTC weekday, Sunday = 0
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1791652883201&limit=5000",
headers={"X-API-Key": API_KEY},
)
# then: jq '.settlements | map(select(.winning_outcome != "")) | group_by((.slug | ltrimstr("btc-updown-5m-") | tonumber / 86400 | floor) + 4 | . % 7) | map({weekday: ((.[0].slug | ltrimstr("btc-updown-5m-") | tonumber / 86400 | floor) + 4 | . % 7), markets: length, up_share: ((map(select(.winning_outcome == "Up")) | length) / length * 1000 | round / 1000)})'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# two weeks of 15-minute ETH outcomes
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=eth-updown-15m-&from_ms=1791652883201&limit=5000",
headers={"X-API-Key": API_KEY},
)
Do Up and Down shares ever cost less than $1 together on 5-minute BTC markets?
Scan a day of archived 5-minute BTC quotes for moments when Up plus Down together cost less than one dollar.
- Uses
/archive/datasets,/archive/url- Verified
- live API, 2026-11-03: 3 calls, all 200
- Downloads
- ≈186 MB
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# where one day of top-of-book quotes for every 5-minute BTC market is, with its size
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=l1_quotes&asset=btc&tenor=5m",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# save the day's quotes locally; DuckDB reads the local copy
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=l1_quotes&asset=btc&tenor=5m&redirect=true",
headers={"X-API-Key": API_KEY},
)
with open("btc-5m-l1_quotes-2026-10-23.parquet", "wb") as f:
f.write(r.content)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the newest days of 5-minute BTC quote files, with sizes
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/datasets?asset=btc&tenor=5m&stream=l1_quotes&limit=3",
headers={"X-API-Key": API_KEY},
)
How long after a 5-minute window closes does the market resolve on-chain?
Take resolved_ts_ms from /settlements/bulk and subtract the window end that the slug encodes.
- Uses
/markets,/settlements,/settlements/bulk- Verified
- live API, 2026-11-03: 6 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# settled 5-minute BTC markets that resolved in the last six hours, oldest resolution first
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792840425357&limit=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# seconds between the end of each 5-minute window and its on-chain resolution
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792840425357&limit=5000",
headers={"X-API-Key": API_KEY},
)
# then: jq '.settlements[] | {slug, lag_s: (.resolved_ts_ms / 1000 - ((.slug | split("-") | last | tonumber) + 300))}'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# settled 5-minute ETH markets from the same six hours
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=eth-updown-5m-&from_ms=1792840425357&limit=3",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# resume strictly after the last row of the previous page
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792840425357&limit=5&cursor=1792841780000:0x7b061dd26a62259ea989c24b8b65c1ef7afdef3482b52115b138c961c9db8be5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the market's end date, epoch ms
r = requests.get(
"https://data.vike.io/v1/polymarket/markets/0x69e0442186b71c5cac4fa6304311e39101ed048983a200fc8e376a9dadd7de13",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the on-chain resolution of the same market
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/0x69e0442186b71c5cac4fa6304311e39101ed048983a200fc8e376a9dadd7de13",
headers={"X-API-Key": API_KEY},
)
Compare the order book of Polymarket's 5-minute and 15-minute crypto Up/Down markets, coin by coin
List one day's per-coin top-of-book files with /archive/datasets, download them, and compute spread, size at the touch and quote updates per market for each coin in DuckDB.
- Uses
/archive/datasets,/archive/url,/settlements/bulk- Verified
- live API, 2026-11-03: 4 calls, all 200
- Downloads
- ≈51 MB
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# every coin's 5-minute top-of-book file for one day, with sizes
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/datasets?tenor=5m&stream=l1_quotes&from=2026-10-23&to=2026-10-23",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the day's 5-minute ETH quotes, saved locally
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=l1_quotes&asset=eth&tenor=5m&redirect=true",
headers={"X-API-Key": API_KEY},
)
with open("eth-5m-l1_quotes-2026-10-23.parquet", "wb") as f:
f.write(r.content)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# every coin's 15-minute top-of-book file for the same day
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/datasets?tenor=15m&stream=l1_quotes&from=2026-10-23&to=2026-10-23",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the 15-minute ETH markets settled on 2026-10-23
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=eth-updown-15m-&from_ms=1792713600000&to_ms=1792800000000&limit=5000",
headers={"X-API-Key": API_KEY},
)
Walk every settled 5-minute BTC market in one script
Call /settlements/bulk?slug_prefix=btc-updown-5m-&limit=5000 and pass each page's next_cursor back as cursor until has_more is false.
- Uses
/settlements/bulk- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# page 1 of the walk: settled 5-minute BTC markets, oldest first
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&limit=5000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# page 2 of the captured walk
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&limit=3&cursor=1767226221000:0x317e2f8941aac42f211ba94384e05b76e10eed874674d70719583fef7571d07b",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# slug, winner and resolution time of each market on the page
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&limit=5000",
headers={"X-API-Key": API_KEY},
)
# then: jq -c '.settlements[] | [.slug, .winning_outcome, .resolved_ts_ms]'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# page 1 of every settled 15-minute ETH market
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=eth-updown-15m-&limit=5000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# everything settled after the last market you hold
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&limit=5000&cursor=1792765880000:0x8c1824d3201d570703ff6a9ac47374327f53b873665abc3f68998704b96bec51",
headers={"X-API-Key": API_KEY},
)
Order book, spread and backtests
Market making, slippage and testing a strategy on the real historical book.
Backtest a Polymarket strategy on the real historical book (fills, fees, lookahead)
Backtest a Polymarket strategy on archived quotes, deciding only on quotes seen before each trade and filling at the standing ask; add fees yourself.
- Uses
/archive/url,/settlements/bulk- Verified
- live API, 2026-11-03: 4 calls, all 200
- Downloads
- ≈186 MB
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# how every 5-minute BTC market resolved on 2026-10-23: the payoff side of the backtest
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792713600000&to_ms=1792800000000&limit=5000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# markets.jsonl: condition_id, slug, Up token and winning token of each market
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792713600000&to_ms=1792800000000&limit=5000",
headers={"X-API-Key": API_KEY},
)
# then: jq -c '.settlements[] | select(.outcomes[0] == "Up") | {condition_id, slug, up_token: .token_ids[0], winning_token_id}' > markets.jsonl
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the top of book of every 5-minute BTC market on 2026-10-23 (186 MB)
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=l1_quotes&asset=btc&tenor=5m&redirect=true",
headers={"X-API-Key": API_KEY},
)
with open("btc-5m-l1_quotes-2026-10-23.parquet", "wb") as f:
f.write(r.content)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# where the day's full-book file is, with its size
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=book_events&asset=btc&tenor=5m",
headers={"X-API-Key": API_KEY},
)
Slippage: what would a $X order have cost at time T?
Take the /orderbook snapshot at T and walk the asks level by level until $X is spent; the average price against the best ask is the slippage, and at most 25 levels a side come back, so a large order can run off the end.
- Uses
/orderbook- Verified
- live API, 2026-11-03: 4 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# a $500 market buy of the Down token at 14:26:40 UTC on 2026-10-23: walk the asks of the book at that moment
r = requests.get(
"https://data.vike.io/v1/polymarket/orderbook?token_id=2124295006397608207923779951408795040669109096087651269807278744579659839433&ts=1792765600000",
headers={"X-API-Key": API_KEY},
)
# then: jq --argjson usd 500 'map(select(.side == "ask")) | unique_by(.level) | reduce .[] as $l ({spent: 0, shares: 0, levels: 0}; if .spent >= $usd then . else ([$l.price * $l.size, $usd - .spent] | min) as $take | .spent += $take | .shares += $take / $l.price | .levels += 1 end) | . + {avg_price: (.spent / .shares), unfilled_usd: ($usd - .spent)}'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the same walk for $20,000: unfilled_usd shows where the returned book ran out
r = requests.get(
"https://data.vike.io/v1/polymarket/orderbook?token_id=2124295006397608207923779951408795040669109096087651269807278744579659839433&ts=1792765600000",
headers={"X-API-Key": API_KEY},
)
# then: jq --argjson usd 20000 'map(select(.side == "ask")) | unique_by(.level) | reduce .[] as $l ({spent: 0, shares: 0, levels: 0}; if .spent >= $usd then . else ([$l.price * $l.size, $usd - .spent] | min) as $take | .spent += $take | .shares += $take / $l.price | .levels += 1 end) | . + {avg_price: (.spent / .shares), unfilled_usd: ($usd - .spent)}'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# a market sell of 3,000 Down shares at the same moment
r = requests.get(
"https://data.vike.io/v1/polymarket/orderbook?token_id=2124295006397608207923779951408795040669109096087651269807278744579659839433&ts=1792765600000",
headers={"X-API-Key": API_KEY},
)
# then: jq --argjson shares 3000 'map(select(.side == "bid")) | unique_by(.level) | reduce .[] as $l ({sold: 0, usd: 0, levels: 0}; if .sold >= $shares then . else ([$l.size, $shares - .sold] | min) as $take | .sold += $take | .usd += $take * $l.price | .levels += 1 end) | . + {avg_price: (.usd / .sold), unsold_shares: ($shares - .sold)}'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the Down token's book at 14:29:00 UTC, one minute before the close
r = requests.get(
"https://data.vike.io/v1/polymarket/orderbook?token_id=2124295006397608207923779951408795040669109096087651269807278744579659839433&ts=1792765740000",
headers={"X-API-Key": API_KEY},
)
Polymarket bid-ask spread and depth history
Download one day of BTC 5-minute top-of-book quotes from the archive and compute median and p90 spread per token with DuckDB.
- Uses
/archive/datasets,/archive/url- Verified
- live API, 2026-11-03: 3 calls, all 200
- Downloads
- ≈179 MB
- Needs
pip install duckdb
The code
"""Quoted-spread statistics for BTC 5-minute Polymarket markets from one downloaded day of l1_quotes, read with DuckDB.
Run: VIKE_API_KEY=... python pm-spread-duckdb.py (--dry-run lists the requests and makes none)
Needs `pip install duckdb` for the real run; --dry-run does not.
"""
import os
import sys
from urllib.parse import urlencode
NAME = "pm-spread-duckdb"
BASE = "https://data.vike.io"
DRY = "--dry-run" in sys.argv
def fail(why):
sys.exit(f"{NAME}: {why}")
def call(path, method="GET", **params):
url = BASE + path + ("?" + urlencode(params) if params else "")
if DRY:
print(method, url)
return None
key = os.environ.get("VIKE_API_KEY") or fail("set VIKE_API_KEY")
import requests
r = requests.request(method, url, headers={"X-API-Key": key}, timeout=60)
if r.status_code != 200:
fail(f"{method} {path} answered HTTP {r.status_code}: {r.text[:200]}")
return r.json()
def download(url, path):
"""The whole file in one request, streamed to disk. DuckDB then reads the LOCAL copy, never the URL."""
if DRY:
print("GET", url)
return
import requests
from urllib.parse import urlparse
# The key only ever goes to our own host. The link /archive/url hands back is presigned: it is its own
# credential (valid 7 days), so it is fetched with no key at all.
headers = {"X-API-Key": os.environ["VIKE_API_KEY"]} if urlparse(url).hostname == "data.vike.io" else {}
with requests.get(url, headers=headers, stream=True, timeout=300) as r:
if r.status_code != 200:
fail(f"GET {url} answered HTTP {r.status_code}")
with open(path, "wb") as f:
for chunk in r.iter_content(chunk_size=1 << 20):
f.write(chunk)
def main():
# The family layout: BTC 5-minute markets only, a much smaller file than the flat day of l1_quotes.
family = dict(asset="btc", tenor="5m", stream="l1_quotes")
index = call("/v1/polymarket/archive/datasets", limit=1000, **family)
day = "2026-09-01" # --dry-run has no response to read
if not DRY:
if not index["datasets"]:
fail("the archive index lists no btc/5m l1_quotes file")
day = max(d["date"] for d in index["datasets"])
meta = call("/v1/polymarket/archive/url", date=day, **family)
url = f"{BASE}/archive/venue=polymarket/asset=btc/tenor=5m/date={day}/l1_quotes.parquet" # --dry-run: the same file's keyed path
if not DRY:
url = meta["url"]
path = f"polymarket-btc-5m-l1-{day}.parquet"
download(url, path)
if DRY:
return
if os.path.getsize(path) != meta["bytes"]:
fail(f"{path} is {os.path.getsize(path)} bytes, the archive says {meta['bytes']} (truncated download?)")
import duckdb
# bid/ask are Decimal(9,4); cast so the arithmetic is plain floats. One row per top-of-book CHANGE, so these
# are statistics over quote updates, not time-weighted spreads.
rows = duckdb.execute(
"""
SELECT token_id, count(*) AS quotes,
median(CAST(ask AS DOUBLE) - CAST(bid AS DOUBLE)) AS median_spread,
quantile_cont(CAST(ask AS DOUBLE) - CAST(bid AS DOUBLE), 0.9) AS p90_spread
FROM read_parquet(?)
WHERE bid > 0 AND ask > 0 AND ask >= bid
GROUP BY token_id ORDER BY quotes DESC LIMIT 5
""",
[path],
).fetchall()
if not rows:
fail(f"{path} holds no usable quotes")
print(f"{day}, BTC 5m, five most-quoted tokens")
for token_id, quotes, median, p90 in rows:
print(f" {token_id[:12]}... {quotes:>7} quotes median spread {median:.4f} p90 {p90:.4f}")
if __name__ == "__main__":
try:
main()
except Exception as e: # a shape the example does not expect fails by name, not by traceback
fail(f"{type(e).__name__}: {e}")
What does Polymarket liquidity look like in the final seconds before a market closes?
Take each 5-minute BTC market's close from its slug (start plus 300 seconds), join a day of archived top-of-book quotes to it, and bucket spread, size at the touch and quote updates by seconds before the close.
- Uses
/archive/url,/settlements/bulk- Verified
- live API, 2026-11-03: 4 calls, all 200
- Downloads
- ≈186 MB
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# a day of settled 5-minute BTC markets: condition ids and slugs, which carry each market's start time
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792713600000&to_ms=1792800000000&limit=5000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# markets.jsonl: one line per market with its condition id and slug
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792713600000&to_ms=1792800000000&limit=5000",
headers={"X-API-Key": API_KEY},
)
# then: jq -c '.settlements[] | {condition_id, slug}' > markets.jsonl
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the top of book of every 5-minute BTC market on 2026-10-23 (186 MB)
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=l1_quotes&asset=btc&tenor=5m&redirect=true",
headers={"X-API-Key": API_KEY},
)
with open("btc-5m-l1_quotes-2026-10-23.parquet", "wb") as f:
f.write(r.content)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# where the day's full-book file is, with its size
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=book_events&asset=btc&tenor=5m",
headers={"X-API-Key": API_KEY},
)
Polymarket order book at a past moment
Pass a timestamp and get the latest recorded Polymarket book snapshot at or before it, up to 25 levels a side.
- Uses
/events,/orderbook- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the Down token's book of a 5-minute BTC market at 14:26:40 UTC on 2026-10-23, 100 seconds into its window
r = requests.get(
"https://data.vike.io/v1/polymarket/orderbook?token_id=2124295006397608207923779951408795040669109096087651269807278744579659839433&ts=1792765600000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# five levels a side at the same moment
r = requests.get(
"https://data.vike.io/v1/polymarket/orderbook?token_id=2124295006397608207923779951408795040669109096087651269807278744579659839433&ts=1792765600000&depth=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# a token near certainty: one-sided book, older snapshot
r = requests.get(
"https://data.vike.io/v1/polymarket/orderbook?token_id=95532524407959903145510583684979049735028502452973932716346555811355282494630&ts=1787180000000&depth=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the same book with any repeated level dropped
r = requests.get(
"https://data.vike.io/v1/polymarket/orderbook?token_id=2124295006397608207923779951408795040669109096087651269807278744579659839433&ts=1792765600000",
headers={"X-API-Key": API_KEY},
)
# then: jq 'unique_by([.side, .level])'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the full-book snapshots of the minute before
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_id=2124295006397608207923779951408795040669109096087651269807278744579659839433&event_type=book&from_ms=1792765540000&to_ms=1792765600000&limit=100",
headers={"X-API-Key": API_KEY},
)
Rebuild the Polymarket order book tick by tick from book events
Read one outcome token's tape from /events, starting at a book snapshot, and replay it in order; a snapshot replaces the ladder, a price_change sets one level, and a gap marker means wait for the next snapshot.
- Uses
/archive/url,/events- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# one token's tape from a book snapshot onward: the snapshot, then every change after it, oldest first
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_id=95532524407959903145510583684979049735028502452973932716346555811355282494630&from_ms=1787180204123&to_ms=1787180804123&limit=6",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the first full-book snapshot inside a window
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_id=95532524407959903145510583684979049735028502452973932716346555811355282494630&event_type=book&from_ms=1787180000000&to_ms=1787183633324&limit=1",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the rows after the last one of the first page
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_id=95532524407959903145510583684979049735028502452973932716346555811355282494630&from_ms=1787180204123&to_ms=1787180804123&limit=50000&cursor=1787180326583:8415:95532524407959903145510583684979049735028502452973932716346555811355282494630",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the Yes and No books of one market, replayed together
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_ids=95532524407959903145510583684979049735028502452973932716346555811355282494630,107869950127184141743772429738701578723770582686430100389837827512148691029625&from_ms=1787180204123&to_ms=1787180804123&limit=50000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# where the day's full-book file is, with its size
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=book_events&asset=btc&tenor=5m",
headers={"X-API-Key": API_KEY},
)
Label every book event in an archive day with its market's outcome
Download a day's book_events (or trades) file from the archive, fetch the same day's settlements from /settlements/bulk, and join on condition_id; token_id equal to winning_token_id marks the events of the token that won.
- Uses
/archive/url,/settlements/bulk- Verified
- live API, 2026-11-03: 4 calls, all 200
- Downloads
- ≈1,653 MB
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# where one day of full-book events for every 5-minute BTC market is, with its size
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=book_events&asset=btc&tenor=5m",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# winners.jsonl: each market's condition id and winning token
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792713600000&to_ms=1792803600000&limit=5000",
headers={"X-API-Key": API_KEY},
)
# then: jq -c '.settlements[] | {condition_id, winning_token_id}' > winners.jsonl
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the day's full-book events, saved locally
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=book_events&asset=btc&tenor=5m&redirect=true",
headers={"X-API-Key": API_KEY},
)
with open("btc-5m-book_events-2026-10-23.parquet", "wb") as f:
f.write(r.content)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# where the day's prints of every 5-minute BTC market are
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=trades&asset=btc&tenor=5m",
headers={"X-API-Key": API_KEY},
)
Traders and smart money
Who wins, how they trade, and whether their profit is real.
Where is Polymarket smart money flowing? Mispriced markets
See where wallets with a record of realized profit put money in the last day, and which of those markets they bought below the mid.
- Uses
/markets/{…},/smart_money- Verified
- live API, 2026-11-03: 3 calls, all 200
The code
"""Where the profitable Polymarket cohort put money in the last day, and which of those markets it also bought below the mid.
Run: VIKE_API_KEY=... python pm-smart-money.py (--dry-run lists the requests and makes none)
"""
import os
import sys
from datetime import datetime, timezone
from urllib.parse import urlencode
NAME = "pm-smart-money"
BASE = "https://data.vike.io"
DRY = "--dry-run" in sys.argv
def fail(why):
sys.exit(f"{NAME}: {why}")
def call(path, method="GET", **params):
url = BASE + path + ("?" + urlencode(params) if params else "")
if DRY:
print(method, url)
return None
key = os.environ.get("VIKE_API_KEY") or fail("set VIKE_API_KEY")
import requests
r = requests.request(method, url, headers={"X-API-Key": key}, timeout=60)
if r.status_code != 200:
fail(f"{method} {path} answered HTTP {r.status_code}: {r.text[:200]}")
return r.json()
def main():
# Dollars, not shares: net_inflow is cohort buys minus cohort sells in the window. Rows come back best first.
flows = call("/v1/polymarket/smart_money", mode="flows", hours=24, limit=5)
# Only clear cases appear here: at least $500 of cohort buying and a 0.03 gap to the mid. [] is a normal answer.
cheap = call("/v1/polymarket/smart_money", mode="mispricings", hours=24, limit=20)
cid = "0xe0b5bd8eef80fe8976e2c287e0b76a5cda138ddc437acf95f9ba91112dbc983d" # --dry-run has no response to read
if not DRY:
if not flows:
fail("no cohort flow in the last 24 hours")
by_market = {m["condition_id"]: m for m in cheap}
for f in flows:
line = f"{f['title']}: net ${f['net_inflow']:,.0f} from {f['smart_wallets']} wallets, yes_mid {f['yes_mid']}"
m = by_market.get(f["condition_id"])
if m:
line += f" | also bought below the mid: {m['side']} at {m['avg_buy_price']}, now {m['current_mid']}"
print(line)
cid = flows[0]["condition_id"]
# The top market's lifecycle: closed is derived, so a settled market reads closed=1 here.
detail = call(f"/v1/polymarket/markets/{cid}")
if DRY:
return
if not detail:
fail(f"{cid} is not in the directory")
d = detail[0]
end = datetime.fromtimestamp(d["end_date"] / 1000, timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
print(f"top market {d['slug']}: closed={d['closed']}, ends {end}")
if __name__ == "__main__":
try:
main()
except Exception as e: # a shape the example does not expect fails by name, not by traceback
fail(f"{type(e).__name__}: {e}")
Which Polymarket wallets are farmers: a high hit rate on a sliver of profit?
Sort /leaderboard by hit_rate with min_resolved=50, then set realized_pnl_usd against volume_all_usd; a 100% rate that returns cents on thousands of dollars is a farmer.
- Uses
/leaderboard- Verified
- live API, 2026-11-03: 4 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# wallets with the highest hit rate over at least 50 resolved markets
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?sort=hit_rate&min_resolved=50&limit=5",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the highest hit rates among wallets with $100,000 or more of lifetime volume
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?sort=hit_rate&min_resolved=50&min_volume_usd=100000&limit=20",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# high hit rates with an average trade of $20 or more
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?sort=hit_rate&min_resolved=50&min_avg_usd=20&limit=20",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# realized P&L as a share of lifetime volume, per wallet
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?sort=hit_rate&min_resolved=50&min_volume_usd=100000&limit=20",
headers={"X-API-Key": API_KEY},
)
# then: jq '.[] | {proxy_wallet, hit_rate, realized_pnl_usd, volume_all_usd, pnl_per_dollar: (.realized_pnl_usd / .volume_all_usd)}'
Market maker or bettor? Classify a Polymarket trader
No field says maker or bettor; read trade count, size and how much a wallet sells back to tell them apart.
- Uses
/leaderboard,/wallets- Verified
- live API, 2026-11-03: 4 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the Crypto wallets with the most resolved markets: where the automated traders are
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?category=Crypto&sort=resolved&limit=3",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# how much of what the wallet bought it sold back before resolution
r = requests.get(
"https://data.vike.io/v1/polymarket/wallets/0xde7be6d489bce070a959e0cb813128ae659b5f4b?window=all",
headers={"X-API-Key": API_KEY},
)
# then: jq '{markets_count, trades_all, avg_trade_usd, shares_bought, shares_sold, sold_back: (.shares_sold / .shares_bought)}'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# per-market buys, sells and trade counts of the first automated trader in the example
r = requests.get(
"https://data.vike.io/v1/polymarket/wallets/0x20d2309cd92b797ae7ca175ed828ed8a27fbe29d?window=all",
headers={"X-API-Key": API_KEY},
)
# then: jq '.markets[] | {title, trades, shares_bought, shares_sold, resolved}'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the Crypto wallets with the most resolved markets, average trade $20 or more
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?category=Crypto&sort=resolved&min_avg_usd=20&limit=20",
headers={"X-API-Key": API_KEY},
)
Polymarket trader profile: realized PnL 24h/7d/30d/all, hit rate, categories
Profile a Polymarket proxy wallet: realized PnL and hit rate over 24h, 7d, 30d or all time, plus its lifetime categories.
- Uses
/leaderboard,/wallets- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# one trader over the last 30 days, beside its lifetime figures
r = requests.get(
"https://data.vike.io/v1/polymarket/wallets/0xde7be6d489bce070a959e0cb813128ae659b5f4b?window=30d",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the last week
r = requests.get(
"https://data.vike.io/v1/polymarket/wallets/0xde7be6d489bce070a959e0cb813128ae659b5f4b?window=7d",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# lifetime: every windowed field covers the whole recorded history
r = requests.get(
"https://data.vike.io/v1/polymarket/wallets/0xde7be6d489bce070a959e0cb813128ae659b5f4b?window=all",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the windowed score in one line
r = requests.get(
"https://data.vike.io/v1/polymarket/wallets/0xde7be6d489bce070a959e0cb813128ae659b5f4b?window=30d",
headers={"X-API-Key": API_KEY},
)
# then: jq '{window, realized_pnl_usd, resolved_markets, hit_rate, hit_rate_ci}'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the top lifetime earners; feed a proxy_wallet to the profile
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?limit=5",
headers={"X-API-Key": API_KEY},
)
Polymarket leaderboard by realized PnL and hit rate, per category
Rank Polymarket wallets by realized PnL or hit rate inside one category, in one request.
- Uses
/leaderboard- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the top Politics wallets by lifetime realized P&L
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?category=Politics&sort=realized_pnl&limit=3",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# Politics wallets by P&L of markets resolved in the last 30 days, bots left out
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?category=Politics&window=30d&sort=realized_pnl_window&min_avg_usd=20&limit=20",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# Sports wallets by hit rate, at least 50 resolved markets and $100,000 of volume
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?category=Sports&sort=hit_rate&min_resolved=50&min_volume_usd=100000&limit=20",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# Crypto wallets with the largest lifetime realized loss
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?category=Crypto&sort=realized_pnl_asc&limit=20",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# ranks 21 to 40 of the Politics board
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?category=Politics&sort=realized_pnl&limit=20&offset=20",
headers={"X-API-Key": API_KEY},
)
Is this Polymarket wallet's profit real? Check realized PnL against on-chain settlements
Take the wallet's markets from /wallets/{address} and check each resolved one against /settlements/{condition_id}, the on-chain winner and resolution time.
- Uses
/leaderboard,/settlements,/wallets- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the wallet's lifetime P&L and the 30 markets it traded most
r = requests.get(
"https://data.vike.io/v1/polymarket/wallets/0xde7be6d489bce070a959e0cb813128ae659b5f4b?window=all",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# once per resolved market: the winner and resolution time from the chain
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/0xd4bbf7f6707c67beb736135ad32a41f6db41f8ae52d3ac4919650de9eeb94ed8",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# P&L of the markets that resolved in the last 30 days
r = requests.get(
"https://data.vike.io/v1/polymarket/wallets/0xde7be6d489bce070a959e0cb813128ae659b5f4b?window=30d",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# condition ids of the resolved markets among the 30 largest
r = requests.get(
"https://data.vike.io/v1/polymarket/wallets/0xde7be6d489bce070a959e0cb813128ae659b5f4b?window=all",
headers={"X-API-Key": API_KEY},
)
# then: jq -r '.markets[] | select(.resolved) | .condition_id'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the Politics board, where this wallet ranks first
r = requests.get(
"https://data.vike.io/v1/polymarket/leaderboard?category=Politics&sort=realized_pnl&limit=3",
headers={"X-API-Key": API_KEY},
)
Markets and trades
Find a market, see how it resolved, read its trades.
Find a Polymarket market by slug, condition_id or token_id; event URL → token ids
Search Polymarket by slug and take the condition and token ids that almost every other call needs.
- Uses
/market_stats,/markets,/markets/{…}- Verified
- live API, 2026-11-03: 3 calls, all 200
The code
"""Search Polymarket markets by slug, then check whether the first hit's outcome token has a recorded tape.
Run: VIKE_API_KEY=... python pm-find-market.py (--dry-run lists the requests and makes none)
"""
import os
import sys
from datetime import datetime, timezone
from urllib.parse import urlencode
NAME = "pm-find-market"
BASE = "https://data.vike.io"
DRY = "--dry-run" in sys.argv
def fail(why):
sys.exit(f"{NAME}: {why}")
def call(path, method="GET", **params):
url = BASE + path + ("?" + urlencode(params) if params else "")
if DRY:
print(method, url)
return None
key = os.environ.get("VIKE_API_KEY") or fail("set VIKE_API_KEY")
import requests
r = requests.request(method, url, headers={"X-API-Key": key}, timeout=60)
if r.status_code != 200:
fail(f"{method} {path} answered HTTP {r.status_code}: {r.text[:200]}")
return r.json()
def when(ms):
return datetime.fromtimestamp(ms / 1000, timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
def main():
# A bare array, latest end_date first. Every other Polymarket route wants an id only this one hands out.
hits = call("/v1/polymarket/markets", query="bitcoin", limit=3)
cid = "0x7b9072e6a9cdcf022c4f098564e8ee612d544e179e4a33dcc2790fbaa778daa8" # --dry-run has no response to read
if not DRY:
if not hits:
fail("no market slug contains 'bitcoin'")
for m in hits:
print(f"{m['slug']} closed={m['closed']} ends {when(m['end_date'])}")
cid = hits[0]["condition_id"]
# A one-element array, not an object; an unknown id is [] with a 200, so test the length.
detail = call(f"/v1/polymarket/markets/{cid}")
token = "95532524407959903145510583684979049735028502452973932716346555811355282494630"
if not DRY:
if not detail:
fail(f"{cid} is not in the directory")
token = detail[0]["token_ids"][0]
print(f"condition_id {cid} tick_size {detail[0]['tick_size']} tokens {len(detail[0]['token_ids'])}")
# One row always comes back; total_events == 0 is how "never recorded" reads.
stats = call("/v1/polymarket/market_stats", token_id=token)
if DRY:
return
s = stats[0]
if s["total_events"] == 0:
print(f"token {token[:12]}...: no recorded tape")
else:
print(f"token {token[:12]}...: {s['total_events']} events, {s['trades']} trades, tape {when(s['first_ms'])} to {when(s['last_ms'])}")
if __name__ == "__main__":
try:
main()
except Exception as e: # a shape the example does not expect fails by name, not by traceback
fail(f"{type(e).__name__}: {e}")
How did this Polymarket market resolve?
The on-chain resolution of one market, with the winning outcome and token, the payout vector, and the block and time it resolved, from /settlements/{condition_id}; [] means the chain resolved nothing.
- Uses
/markets,/settlements,/settlements/bulk- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# how one market ended, from the chain
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/0x69e0442186b71c5cac4fa6304311e39101ed048983a200fc8e376a9dadd7de13",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# how one 5-minute BTC market ended
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/0x8c1824d3201d570703ff6a9ac47374327f53b873665abc3f68998704b96bec51",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# question and winning outcome, or nothing if the chain resolved nothing
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/0x69e0442186b71c5cac4fa6304311e39101ed048983a200fc8e376a9dadd7de13",
headers={"X-API-Key": API_KEY},
)
# then: jq '.[0] | {question, winning_outcome}'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the market's directory row, with active and closed
r = requests.get(
"https://data.vike.io/v1/polymarket/markets/0x69e0442186b71c5cac4fa6304311e39101ed048983a200fc8e376a9dadd7de13",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# every 5-minute BTC market settled on 2026-10-23
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?slug_prefix=btc-updown-5m-&from_ms=1792713600000&to_ms=1792800000000&limit=5000",
headers={"X-API-Key": API_KEY},
)
List every Polymarket market that resolved in the last 24 hours and which side won
Call /settlements/bulk with from_ms set to 24 hours ago; each row is one on-chain resolution with winning_outcome and the payout vector, 5,000 to a page, oldest first, so follow next_cursor until has_more is false.
- Uses
/settlements/bulk- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# every market resolved on chain since 17:21 UTC yesterday, 5,000 to a page, oldest first
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?from_ms=1792776083201&limit=5000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the 5,000 resolutions after the first page
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?from_ms=1792776083201&limit=5000&cursor=1792788273000:0x6979b344509e33e39194463f3bef8a96dbe38491b88a9aeb98c423d7b44dc46a",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# question, winner and resolution time, one line per market
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?from_ms=1792776083201&limit=5000",
headers={"X-API-Key": API_KEY},
)
# then: jq -c '.settlements[] | {question, winning_outcome, resolved_ts_ms}'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the 5-minute BTC markets resolved in the same 24 hours
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?from_ms=1792776083201&slug_prefix=btc-updown-5m-&limit=5000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the markets resolved in the last hour, with their winners
r = requests.get(
"https://data.vike.io/v1/polymarket/settlements/bulk?from_ms=1792858883201&limit=5000",
headers={"X-API-Key": API_KEY},
)
# then: jq -c '.settlements[] | {question, winning_outcome}'
Every trade of a Polymarket market in the last 30 days
Ask /events for event_type=trade on both outcome tokens one 24-hour window at a time; 30 windows cover 30 days, or 30 daily trades files from the archive do. Rows carry no wallets.
- Uses
/archive/url,/events,/market_stats,/markets- Verified
- live API, 2026-11-03: 5 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the last 24 hours of prints on both tokens of one market; repeat with the window moved back a day, 30 times
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_ids=93694900555669388759405753550770573998169287228984912881955464376232163096213,55119388124180116303253993098894090042427725500010038140578121972388485050538&event_type=trade&from_ms=1792776321686&to_ms=1792862721686&limit=50000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# day 2 of 30
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_ids=93694900555669388759405753550770573998169287228984912881955464376232163096213,55119388124180116303253993098894090042427725500010038140578121972388485050538&event_type=trade&from_ms=1792689921686&to_ms=1792776321686&limit=50000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the two outcome tokens of the market
r = requests.get(
"https://data.vike.io/v1/polymarket/markets?query=will-bitcoin-hit-150k-by-december-31-2026&limit=1",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# where the day's file of every print is, with its size
r = requests.get(
"https://data.vike.io/v1/polymarket/archive/url?date=2026-10-23&stream=trades",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# trade count and first and last recorded time of one token
r = requests.get(
"https://data.vike.io/v1/polymarket/market_stats?token_id=93694900555669388759405753550770573998169287228984912881955464376232163096213",
headers={"X-API-Key": API_KEY},
)
Buy versus sell pressure and Yes versus No volume of a Polymarket market, by hour
Fetch a day of trade prints for both outcome tokens from /events with event_type=trade and fold them by hour, token and side; sizes are shares, and price times size is the USDC that changed hands.
- Uses
/events,/market_stats- Verified
- live API, 2026-11-03: 4 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# a day of prints on both tokens of one market, folded into hours: taker buys and sells per token, and USDC traded
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_ids=95532524407959903145510583684979049735028502452973932716346555811355282494630,107869950127184141743772429738701578723770582686430100389837827512148691029625&event_type=trade&from_ms=1787097233324&to_ms=1787183633324&limit=1000",
headers={"X-API-Key": API_KEY},
)
# then: jq '.events | group_by([(.ts / 3600000 | floor), .token_id]) | map({hour: (.[0].ts / 3600000 | floor * 3600 | todate), token: .[0].token_id[0:8], trades: length, buy_shares: (map(select(.side == "buy") | .size) | add // 0 | round), sell_shares: (map(select(.side == "sell") | .size) | add // 0 | round), usd: (map(.price * .size) | add | round)})'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# taker buys and sells of the Yes token, per hour
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_id=95532524407959903145510583684979049735028502452973932716346555811355282494630&event_type=trade&from_ms=1787097233324&to_ms=1787183633324&limit=1000",
headers={"X-API-Key": API_KEY},
)
# then: jq '.events | group_by(.ts / 3600000 | floor) | map({hour: (.[0].ts / 3600000 | floor * 3600 | todate), buy_shares: (map(select(.side == "buy") | .size) | add // 0 | round), sell_shares: (map(select(.side == "sell") | .size) | add // 0 | round)})'
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the 24 hours before the first window
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_ids=95532524407959903145510583684979049735028502452973932716346555811355282494630,107869950127184141743772429738701578723770582686430100389837827512148691029625&event_type=trade&from_ms=1787010833324&to_ms=1787097233324&limit=1000",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# total prints and shares traded on the Yes token since its recording began
r = requests.get(
"https://data.vike.io/v1/polymarket/market_stats?token_id=95532524407959903145510583684979049735028502452973932716346555811355282494630",
headers={"X-API-Key": API_KEY},
)
Tape summary of a Polymarket outcome token (events, first and last recorded)
One row per token with its recorded event count, trade count, shares traded, book snapshots, and the first and last recorded times, from /market_stats.
- Uses
/events,/market_stats- Verified
- live API, 2026-11-03: 4 calls, all 200
The code
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# how much tape one outcome token has, and over what span
r = requests.get(
"https://data.vike.io/v1/polymarket/market_stats?token_id=95532524407959903145510583684979049735028502452973932716346555811355282494630",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the second token of the same market
r = requests.get(
"https://data.vike.io/v1/polymarket/market_stats?token_id=107869950127184141743772429738701578723770582686430100389837827512148691029625",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# a long-running market's first token
r = requests.get(
"https://data.vike.io/v1/polymarket/market_stats?token_id=93694900555669388759405753550770573998169287228984912881955464376232163096213",
headers={"X-API-Key": API_KEY},
)
import os
import requests
API_KEY = os.environ["VIKE_API_KEY"] # your key, read from the environment
# the final hour of this token's recorded tape, prints only
r = requests.get(
"https://data.vike.io/v1/polymarket/events?token_id=95532524407959903145510583684979049735028502452973932716346555811355282494630&event_type=trade&from_ms=1787180033324&to_ms=1787183693324&limit=1000",
headers={"X-API-Key": API_KEY},
)