Schemas Get a free key
Polymarket · Strategies & research

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.

Ask your AI · Claude, ChatGPT, CursorConnect in a minute →

“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_leaderboard
Index

All 28 questions

Jump to any study; ● marks the ones with a finding measured on 2026-11-03.

4 studies

How accurate is Polymarket?

Prices and odds against what actually happened.

How accurate is Polymarket? · API

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
Free APIArchiveStreamMCP
Measured 2026-11-03: A minute before the close the price has almost always decided. Across the last 400 settled BTC 5-minute markets: priced 0.9–1.0, Up won 182 of 182; priced under 0.1, it won 0 of 217. Only 1 market sat in between.
Ask your AI agent: “What was the Up price one minute before the end of the Bitcoin Up or Down 7:10AM-7:15AM ET market of October 24, and which side won?”

The code

python
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},
)
How accurate is Polymarket? · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “Show the Up price of the Bitcoin Up or Down 7:10AM-7:15AM ET market of October 24 minute by minute next to the BTC price”

The code

python
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},
)
How accurate is Polymarket? · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “Show the daily odds of Kylian Mbappe finishing in the top 3 of the 2026 Ballon d'Or”

The code

python
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},
)
How accurate is Polymarket? · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “What is the best bid and ask on Yes for JD Vance winning the 2028 US presidential election?”

The code

python
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
5 studies

5- and 15-minute crypto markets

Up/Down markets: who wins, when, and how fast they settle.

5- and 15-minute crypto markets · API

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
Free APIArchiveStreamMCP
Measured 2026-11-03: Up won 50.1% of 83,278 settled BTC 5-minute markets. By the UTC hour the window starts, it ranges from 48.2% at 13:00 to 52.2% at 14:00.
Ask your AI agent: “How often does Up win on Polymarket 5-minute BTC markets, by UTC hour of the day, over the last two weeks?”

The code

python
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)})'
5- and 15-minute crypto markets · API + archive

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
Free APIArchiveStreamMCP
Ask your AI agent: “Give me the download link for the 5-minute BTC top-of-book quotes of 2026-10-23 on Polymarket”

The code

python
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},
)
5- and 15-minute crypto markets · API

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
Free APIArchiveStreamMCP
Measured 2026-11-03: The chain resolves a 5-minute BTC market a median 48 seconds after its window closes; 90% within 86 seconds (83,279 markets).
Ask your AI agent: “How many seconds after its window closed did the Bitcoin Up or Down 7:10AM-7:15AM ET market of October 24 resolve on chain?”

The code

python
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},
)
5- and 15-minute crypto markets · API + archive

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
Free APIArchiveStreamMCP
Ask your AI agent: “List the Polymarket archive files of the 5-minute crypto Up/Down markets for 2026-10-23, per coin, with their sizes”

The code

python
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},
)
5- and 15-minute crypto markets · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “How did the Polymarket market 0x317e2f8941aac42f211ba94384e05b76e10eed874674d70719583fef7571d07b resolve?”

The code

python
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},
)
7 studies

Order book, spread and backtests

Market making, slippage and testing a strategy on the real historical book.

Order book, spread and backtests · API + archive

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
Free APIArchiveStreamMCP
Ask your AI agent: “Give me the download links of the Polymarket 5-minute BTC top-of-book and full-book files for 2026-10-23”

The code

python
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},
)
Order book, spread and backtests · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “How much would a $500 market buy of Polymarket token 2124295006397608207923779951408795040669109096087651269807278744579659839433 have cost at 14:26:40 UTC on 2026-10-23?”

The code

python
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)}'
Order book, spread and backtests · API + archive

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
Free APIArchiveStreamMCP

The code

python
"""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}")
Order book, spread and backtests · API + archive

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
Free APIArchiveStreamMCP
Ask your AI agent: “Give me the download link for the Polymarket 5-minute BTC top-of-book file of 2026-10-23”

The code

python
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},
)
Order book, spread and backtests · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “What did the Polymarket order book of token 2124295006397608207923779951408795040669109096087651269807278744579659839433 look like at 14:26:40 UTC on 2026-10-23?”

The code

python
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},
)
Order book, spread and backtests · API + archive

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
Free APIArchiveStreamMCP
Ask your AI agent: “Show me the book events of Polymarket token 95532524407959903145510583684979049735028502452973932716346555811355282494630 from 22:56 to 23:06 UTC on 2026-08-19”

The code

python
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},
)
Order book, spread and backtests · API + archive

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
Free APIArchiveStreamMCP
Ask your AI agent: “Give me the download link for the Polymarket 5-minute BTC book_events file of 2026-10-23, with its size”

The code

python
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},
)
6 studies

Traders and smart money

Who wins, how they trade, and whether their profit is real.

Traders and smart money · API

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
Free APIArchiveStreamMCP

The code

python
"""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}")
Traders and smart money · API

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
Free APIArchiveStreamMCP
Measured 2026-11-03: All 50 of the top 50 wallets by hit rate (50+ resolved markets) win more than 90% of their markets (median 100%), at a median realized profit of only $1.72 per market.
Ask your AI agent: “Which Polymarket wallets have a 100% hit rate over at least 50 resolved markets but less than 1% return on their volume?”

The code

python
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},
)
Traders and smart money · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “Is Polymarket wallet 0x20d2309cd92b797ae7ca175ed828ed8a27fbe29d a market maker or a bettor? Show its trade count, average trade and markets”

The code

python
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},
)
Traders and smart money · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “Profile Polymarket wallet 0xde7be6d489bce070a959e0cb813128ae659b5f4b over the last 30 days”

The code

python
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},
)
Traders and smart money · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “Who are the top 10 Polymarket wallets in Politics by realized P&L, with their hit rates?”

The code

python
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},
)
Traders and smart money · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “Profile Polymarket wallet 0xde7be6d489bce070a959e0cb813128ae659b5f4b and check its three largest resolved markets against their on-chain settlements”

The code

python
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},
)
6 studies

Markets and trades

Find a market, see how it resolved, read its trades.

Markets and trades · API

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
Free APIArchiveStreamMCP

The code

python
"""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}")
Markets and trades · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “How did the Polymarket market 0x69e0442186b71c5cac4fa6304311e39101ed048983a200fc8e376a9dadd7de13 resolve?”

The code

python
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},
)
Markets and trades · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “How did the Polymarket market 0x379eea128085e0456b33a736e134285d8ec11107adc61e149791f861d101c0b1 resolve?”

The code

python
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},
)
Markets and trades · API + archive

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
Free APIArchiveStreamMCP
Ask your AI agent: “List the trades of the Polymarket market will-bitcoin-hit-150k-by-december-31-2026 in the last 24 hours”

The code

python
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},
)
Markets and trades · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “Sum the buys and sells of Polymarket tokens 95532524407959903145510583684979049735028502452973932716346555811355282494630 and 107869950127184141743772429738701578723770582686430100389837827512148691029625 by hour for the 24 hours before 2026-08-19 23:53 UTC”

The code

python
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)})'
Markets and trades · API

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
Free APIArchiveStreamMCP
Ask your AI agent: “How much tape does Polymarket token 95532524407959903145510583684979049735028502452973932716346555811355282494630 have, and when does it start and end?”

The code

python
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},
)