“If I had copied every trade this wallet made, how much would slippage friction have eaten?”You pass a wallet and a time window. We walk every fill in that window, apply a realistic 2% slippage on each buy and sell (capped at $1.00 per share for buys), settle redemptions / merges / splits at face value, and return both the wallet’s actual cashflow PnL and the simulated copier’s PnL. The dollar gap between them — divided by the trader’s actual PnL — is the slippage cost rate. A wallet with a high slippage rate (>15%) profits primarily from execution speed and tight spreads. A copier following them with normal latency and slippage won’t replicate the returns. We flag those as
toxic_for_copying.
How the math works
For each fill in the window:- BUY: copier pays
price × 1.02 × shares, capped at1.00 × shares - SELL: copier receives
price × 0.98 × shares
- Processed at face value, no slippage applied to either side
abs(actual_pnl) < $1, the rate denominator is unstable and we return null for the rate.
What “PnL” means here
actual_pnl_usdc is cashflow PnL over the requested window: the real dollars that moved through this wallet’s Safe. It does not mark open positions to current price the way Polymarket’s website does. The response includes a pnl_definition: "cashflow" field to make this explicit.
This is the right number for copy-trading quality scoring because a copier eventually realizes their open positions too — what matters is the friction-adjusted dollars actually banked, not paper marks that can evaporate.
If you want PM-website style realized + unrealized PnL, use the Trader PnL Series endpoint.
Per-position metrics: parity with Polymarket
Theavg_entry_prob_weighted and positions_closed fields are computed via per-position weighted-average cost basis matching across every fill, split, merge, redemption, and neg-risk conversion in the requested window — the same method used to match Polymarket’s own data-api.
Validation against data-api.polymarket.com/positions realizedPnl across 30 positions on diverse wallets (standard CTF + neg-risk markets):
| Threshold | Match rate |
|---|---|
| sub-penny | 97 % |
| sub-$1 | 100 % |
| sub-$10 | 100 % |
Endpoints
Score on demand:| Method | Endpoint | Description |
|---|---|---|
GET | /v2/copy-pnl/{wallet} | Score one wallet over a time window |
POST | /v2/copy-pnl/batch | Score up to 100 wallets in one call |
| Method | Endpoint | Description |
|---|---|---|
POST | /v2/copy-pnl/wallets | Add wallets to your private tracked-pool |
DELETE | /v2/copy-pnl/wallets | Remove wallets from your pool |
GET | /v2/copy-pnl/wallets | List wallets in your pool |
GET | /v2/copy-pnl/leaderboard | Sorted, filtered, paginated leaderboard over your pool |
BYOB — when to use it
The on-demand endpoints (GET /v2/copy-pnl/{wallet} and POST /v2/copy-pnl/batch) are synchronous — you wait while we walk the wallet’s history, which can take up to 30 seconds per wallet. Great for one-off lookups.
BYOB inverts that. You hand us a list of wallets you care about; we precompute their copy-pnl scores in the background across multiple time windows; you query the resulting leaderboard with sub-second latency. Best for:
- Picking leader wallets to surface in your UI from a candidate pool
- Daily-refreshed dashboards
- Anywhere you need “top N by backtest_copy_pnl_usdc, excluding toxic, with min trade count” answered fast
- POST your wallet list to
/v2/copy-pnl/wallets(max 1000 wallets per API key) - Newly-added wallets get scored immediately (on-add freshening — usually within ~30s of the add)
- The full pool also refreshes daily in the background
- Query
/v2/copy-pnl/leaderboardto read sorted/filtered results — all from cache, sub-second - Each result row includes
computed_atso you can show freshness in your UI
Time-window options
- Default: last 30 days (when no
from,to, orperiodis provided) - Preset:
?period=7d|14d|30d|60d|90d|180d - Explicit:
?from=YYYY-MM-DDand/or?to=YYYY-MM-DD(also accepts unix seconds) - Precedence: explicit
from/tobeatsperiodbeats default
Time-window options
- Default: last 30 days (when no
from,to, orperiodis provided) - Preset:
?period=7d|14d|30d|60d|90d|180d - Explicit:
?from=YYYY-MM-DDand/or?to=YYYY-MM-DD(also accepts unix seconds) - Precedence: explicit
from/tobeatsperiodbeats default
Limits and behavior
On-demand endpoints ({wallet} + batch):
- Paid tier required — free tier returns 403
- Rate limit: 1 request per 5 seconds per API key (backtest is compute-heavy)
- Server budget: 30 second hard cap on the underlying walk. Extreme high-frequency wallets (1M+ fills in the window) may return
partial: true— pass a tighter window to fit in budget - Maximum window:
180d(6 months). Past that, even normal wallets exceed budget - Batch: max 100 wallets per call
- Pool size: 1000 wallets per API key max
- Refresh cadence: 24 hour periodic cycle, processed in chunks of 50 wallets spread across the day. Plus on-add freshening (new wallets scored immediately, usually within seconds).
- Per-wallet budget on background refresh: 180 seconds (3 minutes) — longer than the on-demand 30s cap because the customer isn’t waiting on the response
- Leaderboard query latency: sub-second (all reads from cache)
- Freshness signal: every result row includes
computed_at(unix ts of when that score was last computed); top-level response includeslast_refresh(last full-cycle complete)
FAQ: Why do two traders on the same market get different rates?
The math (2% friction per fill) is identical for every wallet. What changes between traders is how many fills they need to extract their PnL, and how big that PnL is. The rate isslippage / |actual_pnl| — same numerator math, different denominators and trade counts.
The cleanest rule of thumb: the more trades it takes to extract a given dollar of PnL, the less of that PnL survives reproduction.
| Wallet | Strategy | Actual PnL | Trades | Slip $ | Rate | Copyable? |
|---|---|---|---|---|---|---|
0x4924…3782 | Concentrated whale: few large positions held to resolution | $20.0M | 8K | $786K | 3.9 % | Yes — copier captures ~$19.2M |
0x37c1…74a6 | Profitable scalper: tight spreads, fast execution | +$755K | 93K | $925K | 122 % (toxic) | No — copier ends up at -$170K |
0xee61…fc18 | High-frequency loser: many fills for tiny per-trade margin | -$132K | 303K | $929K | 705 % (toxic) | No — copier loses 7x what they did |
- Strategic edge (market reads, conviction, timing of large positions) → low rate, reproducible
- Execution edge (HFT, queue priority, spread capture) → high rate, not reproducible

