How to Build a Polymarket Wallet Tracker Using the Public API?

In prediction markets, information is power but knowing who is betting is often more valuable than knowing what is being bet. While the Polymarket leaderboard shows you the top earners, it doesn’t give you the real-time insights needed to replicate their success before the odds shift.

Imagine getting an alert the moment a “whale” opens a massive position in a niche market, or automatically tracking the portfolio of a trader with a 90% win rate. Because Polymarket is built on the Polygon blockchain, this data is public, you just need the right tools to harvest it.

In this guide, we’ll walk through how to build a custom Polymarket wallet tracker using the public API. We will cover how to fetch user positions, filter for high-value trades, and build a Python script that helps you trade alongside the “smart money.”

Understanding Polymarket’s Architecture

Polymarket operates on Polygon (formerly Matic), a layer-2 Ethereum scaling solution. All trades are executed through a Central Limit Order Book (CLOB) system, but the data is queryable through two main interfaces: the CLOB API (for trading) and the Data API (for history and analytics).

Crucial Note: Users on Polymarket do not trade directly from their MetaMask/EOA address. Instead, they use a Proxy Wallet (often a Gnosis Safe) created by Polymarket. When tracking a user, you must use their Proxy Address (visible in their profile URL), or you will see zero trades.

Prerequisites

You’ll need Python 3.8 or higher and basic familiarity with REST APIs. Install the required dependencies:

Bash

pip install requests pandas python-dotenv

Core API Endpoints

We will use these key endpoints for our tracker:

  • Trades Endpoint: https://data-api.polymarket.com/trades — Returns complete trade history (Maker + Taker).
  • Activity Endpoint: https://data-api.polymarket.com/activity — Captures redemptions (when a user claims winnings), which is vital for accurate P&L.
  • Gamma Endpoint: https://gamma-api.polymarket.com/markets — Provides market metadata like “Yes/No” resolution status.

Building the Basic Tracker

We will create a class that handles the API connections. Note that we use the Data API for trades because it simplifies pagination and captures all trade types.

Python

import requests
import pandas as pd
import time

class PolymarketWalletTracker:
    def __init__(self):
        self.data_url = "https://data-api.polymarket.com"
        self.gamma_url = "https://gamma-api.polymarket.com"

    def get_trades(self, wallet_address):
        """
        Fetch ALL trade history (Maker + Taker) handling pagination.
        The Data API limits responses to 100 trades per call, so we loop
        until no more data is returned.
        """
        all_trades = []
        offset = 0
        limit = 100
        
        while True:
            endpoint = f"{self.data_url}/trades"
            params = {
                'user': wallet_address,
                'limit': limit,
                'offset': offset
            }
            
            try:
                resp = requests.get(endpoint, params=params)
                resp.raise_for_status()
                data = resp.json()
                
                # If list is empty, we have reached the end
                if not data:
                    break
                
                all_trades.extend(data)
                
                # If we received fewer items than the limit, it's the last page
                if len(data) < limit:
                    break
                    
                offset += limit
                # Be kind to the API
                time.sleep(0.1)
                
            except Exception as e:
                print(f"Error fetching trades: {e}")
                break
                
        return all_trades

    def get_activity(self, wallet_address):
        """Fetch redemption and settlement activity"""
        endpoint = f"{self.data_url}/activity"
        params = {'user': wallet_address}
        try:
            response = requests.get(endpoint, params=params)
            response.raise_for_status()
            return response.json()
        except Exception as e:
            print(f"Error fetching activity: {e}")
            return []

Calculating Position and P&L

The challenge in tracking wallets is calculating “Net Cash Flow.” We track how much USDC left the wallet (Buys) versus how much returned (Sells + Redemptions).

Python

    def calculate_pnl(self, wallet_address):
        """Calculate comprehensive P&L for a wallet"""
        trades = self.get_trades(wallet_address)
        activity = self.get_activity(wallet_address)
        
        positions = {}
        total_invested = 0  # Cash flowing OUT (Buying)
        total_returned = 0  # Cash flowing IN (Selling + Redeeming)
        
        # 1. Process Trades
        for trade in trades:
            # Handle potential key variations between API versions
            token_id = trade.get('asset_id') or trade.get('asset')
            side = trade['side']  # 'BUY' or 'SELL'
            size = float(trade['size'])
            price = float(trade['price'])
            cost = size * price
            
            if token_id not in positions:
                positions[token_id] = {
                    'quantity': 0,
                    'cost_basis': 0,
                    'market_id': trade.get('market')
                }
            
            if side == 'BUY':
                positions[token_id]['quantity'] += size
                positions[token_id]['cost_basis'] += cost
                total_invested += cost
            else:  # SELL
                positions[token_id]['quantity'] -= size
                positions[token_id]['cost_basis'] -= cost
                total_returned += cost
        
        # 2. Process Redemptions (Winnings)
        for event in activity:
            if event['type'] == 'redeem':
                # Redemption value is often stored in 'amount' or 'value'
                val = float(event.get('value', 0) or event.get('amount', 0))
                total_returned += val
        
        # Net Profit = (Money Out) - (Money In)
        realized_pnl = total_returned - total_invested
        
        return {
            'total_invested': total_invested,
            'total_returned': total_returned,
            'realized_pnl': realized_pnl,
            'positions': positions
        }

Handling Market Status & Real-Time Prices

To calculate Unrealized P&L (the value of tokens still held), we need live prices. The Gamma API is the easiest way to fetch this data.

Python

    def get_market_price(self, market_id, token_id):
        """Get latest mid-market price from Gamma API"""
        endpoint = f"{self.gamma_url}/markets/{market_id}"
        try:
            resp = requests.get(endpoint)
            data = resp.json()
            # Gamma returns a list of outcomes (tokens); find the one matching our token_id
            if 'tokens' in data:
                for token in data['tokens']:
                    if token.get('tokenId') == token_id:
                        return float(token.get('price', 0))
            return 0
        except:
            return 0

Building a Complete Dashboard

Finally, we combine everything to generate a report. This function iterates through open positions, fetches their current value, and summarizes the wallet’s performance.

Python

    def generate_wallet_report(self, wallet_address):
        """Generate complete wallet performance report"""
        pnl_data = self.calculate_pnl(wallet_address)
        
        unrealized_value = 0
        active_positions = 0
        
        print(f"Analyzing wallet: {wallet_address}...")
        
        for token_id, position in pnl_data['positions'].items():
            # Only check price if we still hold the position
            if position['quantity'] > 0.1:  # Filter out dust
                market_id = position['market_id']
                current_price = self.get_market_price(market_id, token_id)
                position_value = position['quantity'] * current_price
                unrealized_value += position_value
                active_positions += 1
        
        total_equity = pnl_data['realized_pnl'] + unrealized_value
        
        return {
            'wallet': wallet_address,
            'realized_pnl': round(pnl_data['realized_pnl'], 2),
            'open_positions_value': round(unrealized_value, 2),
            'total_account_value': round(total_equity, 2),
            'active_bet_count': active_positions
        }

Rate Limiting and Best Practices

Polymarket’s API is robust but has rate limits. If you plan to track multiple wallets:

  1. Cache Prices: Market prices don’t change every millisecond. Cache price results for 15-30 seconds to reduce API calls.
  2. Database Storage: For production systems, save trade history to a local database (like SQLite or PostgreSQL) so you only need to fetch new trades on subsequent updates.
  3. Error Handling: Always wrap network requests in try/except blocks to prevent a single timeout from crashing your entire tracker.

Testing Your Tracker

Start by tracking well-known public wallets from the leaderboard. Cross-reference your calculated P&L with their public profile stats. If you see a discrepancy, check if you are missing “Redemption” events, as this is the most common source of error in P&L calculations.

How to Use the Polymarket API with Python (Step by Step)

This tutorial provides a visual guide to setting up your Python environment and making your first requests to the Polymarket API, effectively supplementing the code in this article.

TradetheOutcome.com

TradetheOutcome.com

I'm a freelance web developer and market analyst with a passion for turning data into actionable insights. Combining years of experience in web technology, statistics, and the world of prediction markets, I help readers understand probabilities, event trends, and the strategies behind informed trading.

I'm actively engaged in cybersecurity, fintech, and real-time forecasting, I strive to make prediction market analysis accessible and practical for everyone from curious beginners to seasoned traders. Join me on TradeTheOutcome.com as we unlock smarter ways to forecast, trade, and learn from the world’s most dynamic event markets.