API · Reference

The Data API at data-api.polymarket.com is Polymarket's read-only "warehouse" — every wallet's positions, the full trade tape, and live portfolio value, with built-in PnL. It's completely public: no key, no signing, no account. That makes it the easiest place to start — you can build a whole analytics or copy-trading bot off it without ever touching a private key. Every example below is a real call you can run in the sandbox on this page.

At a glance
  • Base URL: https://data-api.polymarket.com · no authentication.
  • Address to pass: the trader's proxy wallet (their on-chain Polymarket address), not a signing key.
  • Rate limit: ~1,000 req / 10s (/trades 200, /positions 150) — throttled, not rejected.
  • Returns plain JSON arrays. Pair with Gamma (discovery) and CLOB (trading).

/positions — what a wallet holds (with PnL)

The workhorse endpoint. Pass a wallet and get every open position, each already enriched with cost basis and profit/loss — so this doubles as the PnL endpoint (no subgraph math needed).

import requests
r = requests.get("https://data-api.polymarket.com/positions",
                 params={"user": PROXY_ADDRESS})
for p in r.json():
    print(p["title"], p["outcome"], p["size"],
          "avg", p["avgPrice"], "pnl", p["cashPnl"])
curl -s "https://data-api.polymarket.com/positions?user=$PROXY_ADDRESS"

Real response (one position, trimmed):

[
  {
    "proxyWallet": "0xbfd068…a0c8",
    "asset":       "30114730…931285",   // the token_id (CLOB-tradeable)
    "conditionId": "0x4589bb…b3005c",
    "size":         100,                 // shares held
    "avgPrice":     0.01,                // your cost basis
    "curPrice":     0.00,                // current mark
    "currentValue": 0.00,
    "cashPnl":     -1.00,                // $ profit/loss
    "percentPnl":  -100,
    "realizedPnl":  0,
    "redeemable":   true,                // market resolved → can redeem
    "title":   "Bitcoin Up or Down - June 14, 8:00-8:05AM ET",
    "outcome": "Down", "outcomeIndex": 1
  }
]
FieldMeaning
assetThe token_id — feed it straight to the CLOB to read the book or trade.
size / avgPriceShares held and your average entry price (cost basis).
cashPnl / percentPnl / realizedPnlUnrealized $, unrealized %, and realized $ — the PnL you'd otherwise compute yourself.
redeemabletrue once the market resolves and the position can be cashed out.

/trades — the trade tape

Every fill, newest first. Filter by user= (one wallet's history) and/or market=, or just pull the firehose with limit=. This is your back-test and copy-trading data source.

curl -s "https://data-api.polymarket.com/trades?user=$PROXY_ADDRESS&limit=100"

Real response (one trade, trimmed):

[
  {
    "proxyWallet": "0xad05d2…3a3d",
    "side":        "BUY",
    "asset":       "54898429…124028",   // token_id traded
    "conditionId": "0x0e6eb3…a83290",
    "size":         10,
    "price":        0.10,
    "timestamp":    1781469243,          // unix seconds
    "title":  "Bitcoin Up or Down - June 14, 4:30-4:35PM ET",
    "outcome": "Down", "outcomeIndex": 1,
    "transactionHash": "0x4c0e78…38064d" // verify on PolygonScan
  }
]

Each trade carries the proxyWallet behind it — so /trades is also how you discover wallets to follow: pull recent fills on a market, then pull each wallet's /positions.

/value — portfolio value in one number

The fastest health check — a wallet's total current value:

v = requests.get("https://data-api.polymarket.com/value",
                 params={"user": PROXY_ADDRESS}).json()[0]["value"]
print(f"${v:,.2f}")
curl -s "https://data-api.polymarket.com/value?user=$PROXY_ADDRESS"

Real response:

[ { "user": "0xbfd068…a0c8", "value": 2.3236 } ]

Recipe: a 20-line wallet tracker

Discover an active wallet from the tape, then dump its book with PnL — all keyless:

import requests
D = "https://data-api.polymarket.com"

# 1) who just traded BTC?
who = requests.get(f"{D}/trades", params={"limit": 1}).json()[0]["proxyWallet"]

# 2) their open book + live PnL
for p in requests.get(f"{D}/positions", params={"user": who}).json():
    print(f"{p['title'][:40]:40} {p['outcome']:4} {p['size']:>6} sh  "
          f"PnL ${p['cashPnl']:+.2f} ({p['percentPnl']:+.0f}%)")

# 3) their total value
print("total $", requests.get(f"{D}/value", params={"user": who}).json()[0]["value"])
Pass the proxy wallet. Use the trader's Polymarket proxy address (the one that holds funds and shows on the leaderboard), not a signing/EOA key. And remember the timestamps are unix seconds.

Next: CLOB API (read the book, trade) · Gamma API (find markets) · Build a copy-trading bot.