# PolyTape Data API — Agent Guide > PolyTape is the trader-intelligence layer for AI agents: every Polymarket > trader's full on-chain history, their live stream, and your recorded tapes. > This file is the read-only data plane for AI agents and scripts. Point an > agent at this guide and it can discover every endpoint, page results, chart a > market, and read a trader end-to-end. V1 is READ-ONLY (no writes, no trading). > > Want worked recipes, a charting spec + ready templates, and token-cost > guidance? A fuller skill lives at https://polytape.io/skill/SKILL.md > (references under /skill/reference/, charts at /skill/reference/plotting.md). ## Base URLs - REST: https://api.polytape.io/api/agent/v1 - MCP: https://api.polytape.io/mcp (FastMCP, streamable HTTP, stateless) - OpenAPI: https://api.polytape.io/api/agent/v1/openapi.json ## Authentication Header only — a key is never accepted in a query string. Authorization: Bearer td_live_... Mint and manage keys in the dashboard: AI Agents & API -> Patch Bay. The plaintext key is shown once at mint time. MCP clients may also connect over OAuth (Clerk) when enabled — you sign in instead of pasting a key. REST, MCP, and OAuth all draw on ONE per-user budget. After an API update, re-add the MCP connector (it caches the tool list). ## Conventions - All responses are JSON. Every read is a GET. - Pagination is cursor-based and forward-only: pass `cursor` (opaque) and an optional `limit`; the response carries `next_cursor` when more pages exist (absent/null means the end). Never hand-craft a cursor — a malformed one is a 400, and a well-formed forged one silently re-returns page 1 (you re-pay for data you have). `limit` must be >= 1. - `{trader}` accepts a 0x wallet address, a polymarket.com profile URL, or a display name (e.g. GoingInsolvent). A wrong-length `0x…` string is a 400 invalid_wallet, not a name lookup. - Timestamps are epoch SECONDS. Money fields are USD, suffixed `_usd`. Prices are UP-normalized (0-1). - Token-thrift: prefer cards/summaries/top-markets over raw arrays, and PASS `limit` (lists/fills) or `points` (charts). A full markets page is ~16k tokens over REST / ~35k over MCP; `limit=20` is ~2k. A sampled `get_market_events` (~300 pts) is one call for the whole chart. - History depth is plan-gated: Basic Intelligence (free) sees the 20 most-recent markets per trader; Pro / Max Intelligence see full history. ## REST endpoints (base = /api/agent/v1) ### Orient - GET /me Plan (Basic Intelligence | Pro Intelligence | Max Intelligence), rate limits, usage this window + day/month, calling key. Mirrors the MCP `whoami` tool. Start here. - GET /popular Curated popular traders with display names and live watching counts. ### Traders (on-chain history — depth by plan: Basic 20 markets, Pro/Max full) - GET /traders/{trader} Career card, blended with Polymarket's profile. THE PnL = `polymarket.pnl` (their model: realized + unrealized, full history incl. pre-V2). Archive fields (markets_total, winrate, volume, avg_entry_price = avg cost per token = the break-even winrate, avg_win_usd, avg_loss_usd, position facts) cover the V2 era. If the upstream is down, polymarket degrades to {status: "pm_offline"} and only then does the card carry the archive's realized career_pnl_usd as the fallback PnL. Start every trader analysis here. - GET /traders/{trader}/top-markets[?n=] The biggest wins/losses (resolved only), most-traded, and top-volume markets in ONE scan. The whale drill-down the recency-only markets list can't do. n<=20. - GET /traders/{trader}/markets[?cursor=&limit=] Recency-ordered market rows with per-market pnl/outcome/fill counts. Pass `limit`. Depth is plan-gated (Basic 20 most-recent · Pro/Max full). For extremes use /top-markets. - GET /traders/{trader}/markets/{condition_id}/summary The computed stat block (no arrays): entry VWAP, buy/sell split, size p50/p90/max, hold time, first/last-tenth money share, outcome/pnl/roi, and a per-token `sides` block. Prefer this over raw events. - GET /traders/{trader}/markets/{condition_id}[?from_ts=&to_ts=&points=&resolution=&raw=] THE SAMPLED MARKET CHART in one call: market + trader + series {from_ts,to_ts, fidelity, points:[[ts,last,lo,hi]]} (UP-normalized; draw (lo+hi)/2) + the trader's COMPLETE fills, each with token_side + outcome. points default 300 (clamp 20-600; ask 120 for chat). raw=1 = the old verbatim ticks+cursor export path (duplicates ~36x). Charting spec: /skill/reference/plotting.md. - GET /traders/{trader}/markets/{condition_id}/tape The whole market as a change-compressed per-second tape ({market, trader, tape: [[ts,last,lo,hi]]}) in ONE gzip response, uncapped — for the interactive full-tape chart. - GET /traders/{trader}/pnl-series[?window=] Polymarket's cumulative-P/L series for the career equity curve: series:[[ts,pnl]] + peak/low/max_drawdown/as_of. window = 24h|7d|30d|ytd|1y|all (default all). - GET /traders/{trader}/fills[?since=&cursor=&limit=] Cross-market fills since a timestamp — the monitoring primitive (any wallet, no live-slot cost). Each fill carries token_side + outcome. Poll with next_cursor. PnL semantics (three voices): polymarket.pnl is the HEADLINE (Polymarket's model, full history). Per-market pnl_usd (and the card's career_pnl_usd, which appears only when polymarket is pm_offline) are realized cash flow only, chain-audited, V2 era — big open books read more negative (open money counts as spent). pnl_marked_usd = realized + open holdings at the last on-chain trade (the chain approximation, not the headline). A resolved market's pnl_usd is a result; an open market's is CASH FLOW (quote pnl_marked_usd, say "marked", never "won $X"). Split/merge legs live inside pnl_usd and never appear as fills, so don't reconstruct pnl from visible fills and don't quote roi on split-sellers. Counts/winrate/volume cover the V2 era until the v1 backfill; the headline covers the full account. A few dozen NegRisk-conversion arb bots read oddly. None of these is a live account balance. ### Your tapes (recorded watch sessions) - GET /tapes[?wallet=&limit=] Your cassette library with metadata. `wallet` narrows to one folder; cap with `limit`. - GET /tapes/{tape_id} One cassette: metadata + summary counts. - GET /tapes/{tape_id}/events[?cursor=&types=&limit=] Parsed StreamEvent pages. `types` is a comma list, e.g. `types=fill`. Oversized tapes are pointed at /download. - GET /tapes/{tape_id}/download Presigned .jsonl.gz URL (valid 1h) — the bulk-export path. ## Rate limits (per user — all keys share one budget) Each request pays a token bucket (refill = rps, capacity = burst) plus a rolling 60-second ceiling (rpm) plus a call quota. Basic Intelligence's quota is DAILY (resets midnight UTC); Pro / Max Intelligence are MONTHLY (reset month start): plan rps burst rpm quota Basic Intelligence 0.5 10 30 50 / day Pro Intelligence 5 60 300 50,000 / month Max Intelligence 20 200 1,200 300,000 / month Basic Intelligence is a daily taste (50 calls/day ≈ one trader crack). Extra keys are parallel plugs, not extra budget. Heavy reads (tape events, market ticks) also pass an admission lane; overflow is an instant, honest 429 rather than a queue. MCP protocol handshakes (connect, tools/list, prompt fetch) do NOT count — only tool calls do. Application 4xx/404 errors on real routes DO burn a call; 429 rejections do not. ## Errors Structured JSON: {"error": "", "message": "", "retry_after"?: } - 400 bad_cursor / bad_limit / invalid_wallet — malformed request (limit must be >= 1) - 401 unauthorized — missing / invalid / revoked key (WWW-Authenticate: Bearer) - 403 depth_gated — market past your history window (Basic Intelligence = 20 markets); upgrade for full history, else treat as not found - 404 not_found / unknown_trader / tape_not_found — no such market / name / tape - 429 rate_limited — bucket or rpm ceiling hit; honor the Retry-After header (seconds) - 429 daily_limit / monthly_limit — the PAYWALL (Basic = daily, Pro/Max = monthly). `message` names the upgrade + https://polytape.io/pricing; relay it to your human, do not silently retry - 429 busy — heavy-read admission lane full; retry shortly - 504 query_timeout — query too broad (or top-markets n too large); narrow and retry - 503 agent_api_disabled / archive_offline / pm_offline — surface/upstream off; retry later Agents should back off on any 429 and respect Retry-After. Transient limits (rate_limited/busy) clear in seconds; the daily/monthly cap is the paywall — relay it. ## MCP Server URL: https://api.polytape.io/mcp Tools (13): whoami · list_popular_traders · get_trader_card · get_top_markets · list_trader_markets · get_market_summary · get_market_events · get_pnl_series · get_recent_fills · get_chart_template · list_tapes · get_tape_summary · get_tape_events Every tool returns its payload as both text and structured JSON, so paged tools cost roughly double their REST equivalent — pass `limit`/`points` on list_trader_markets, get_recent_fills, get_market_events, and get_tape_events. Every tool call costs 1 request (get_chart_template included — no exemptions); protocol handshakes (connect, tools/list, prompt fetch) are free. Prompt: crack_this_trader — read a trader end-to-end and describe how they actually trade (ends with a chart if your interface renders one). Install in Claude Code: claude mcp add --transport http polytape https://api.polytape.io/mcp --header "Authorization: Bearer td_live_..." Works in Claude Code, Cursor, Windsurf, opencode, the claude.ai custom connector, and any MCP client. ## Full schemas Every endpoint, parameter, and response schema is in the scoped OpenAPI document: https://api.polytape.io/api/agent/v1/openapi.json