$npx -y skills add agiprolabs/claude-trading-skills --skill polymarket-apiPolymarket exchange mechanics — on-chain Polygon CTF, Gamma/CLOB/Data APIs, EIP-712 auth, identifier model, WebSocket, settlement, and geo/KYC constraint
| 1 | # Polymarket API |
| 2 | |
| 3 | Polymarket is a **prediction market on Polygon mainnet**. Every market is a pair of YES/NO **ERC-1155** tokens issued by the Conditional Token Framework (CTF), collateralized 1:1 in USDC. Off-chain CLOB matching, on-chain settlement, **zero taker fees**. Prices are in [0.00, 1.00] USDC; YES + NO ≈ 1.0 per market. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | > **Before you write any API code — read the live docs first.** |
| 8 | > |
| 9 | > - Docs: https://docs.polymarket.com |
| 10 | > - Official Python SDK: https://github.com/Polymarket/py-clob-client |
| 11 | > |
| 12 | > Polymarket endpoints and auth flows have changed without notice. Prefer the official `py-clob-client` SDK over hand-rolled HTTP; it handles EIP-712 derivation, API credential management, and order signing. Only hand-roll when the SDK doesn't expose what you need. |
| 13 | |
| 14 | --- |
| 15 | |
| 16 | ## Identifier model |
| 17 | |
| 18 | You will juggle four distinct IDs — get them confused and queries silently return wrong data. |
| 19 | |
| 20 | | ID | What it is | |
| 21 | |----|-----------| |
| 22 | | `condition_id` | On-chain hex ID of the market (the CTF condition) | |
| 23 | | `clob_token_ids` | The YES/NO **pair** of ERC-1155 token IDs — a two-element list | |
| 24 | | `token_id` | A **single** outcome token — what you pass to order-book and WebSocket queries | |
| 25 | | `event_id` | Parent grouping (e.g. all brackets for "NYC high today") | |
| 26 | |
| 27 | --- |
| 28 | |
| 29 | ## Quick Start |
| 30 | |
| 31 | ### 1. Read markets — Gamma API (no auth required) |
| 32 | |
| 33 | ```python |
| 34 | import httpx |
| 35 | |
| 36 | # CRITICAL: default sort is OLDEST-first — always override or you silently get closed markets |
| 37 | events = httpx.get("https://gamma-api.polymarket.com/events", params={ |
| 38 | "tag_id": 103040, # category tag (e.g. weather) |
| 39 | "order": "endDate", |
| 40 | "ascending": "false", # must be string "false", not bool |
| 41 | "closed": "false", |
| 42 | }).json() |
| 43 | |
| 44 | # Each event → markets[], each market has: |
| 45 | # condition_id, clob_token_ids (YES/NO pair), question, outcomes, outcomePrices |
| 46 | for event in events: |
| 47 | for mkt in event.get("markets", []): |
| 48 | yes_token, no_token = mkt["clobTokenIds"] # split the pair here |
| 49 | print(mkt["question"], mkt["outcomePrices"]) |
| 50 | ``` |
| 51 | |
| 52 | **Pagination:** `limit=100&offset=N`, step by 100. |
| 53 | |
| 54 | ### 2. Order book and trading — CLOB API (EIP-712 auth) |
| 55 | |
| 56 | ```bash |
| 57 | uv pip install py-clob-client |
| 58 | ``` |
| 59 | |
| 60 | ```python |
| 61 | import os |
| 62 | from py_clob_client.client import ClobClient |
| 63 | |
| 64 | client = ClobClient( |
| 65 | "https://clob.polymarket.com", |
| 66 | chain_id=137, # Polygon mainnet |
| 67 | key=os.environ["POLYMARKET_PRIVATE_KEY"], # wallet private key — env only, NEVER hardcode |
| 68 | signature_type=2, # 2 = Gnosis Safe proxy (Polymarket UI accounts) |
| 69 | # 0 = direct EOA you fully control |
| 70 | ) |
| 71 | # Derives API key/secret/passphrase from the wallet signature — call once per session |
| 72 | client.set_api_creds(client.create_or_derive_api_creds()) |
| 73 | |
| 74 | token_id = "<yes_token_from_clob_token_ids>" |
| 75 | book = client.get_order_book(token_id) # bids/asks for one outcome token |
| 76 | price = client.get_price(token_id, side="BUY") |
| 77 | ``` |
| 78 | |
| 79 | `signature_type=2` is for the proxy/Safe accounts the Polymarket web UI creates (the funder address is the Safe). Use `signature_type=0` for a raw EOA you control directly. Read the live SDK docs — the type you choose affects how orders are signed on-chain. |
| 80 | |
| 81 | Wallet env vars: `POLYMARKET_PRIVATE_KEY`, `POLYMARKET_FUNDER`. Never hardcode keys. |
| 82 | |
| 83 | --- |
| 84 | |
| 85 | ## API surface overview |
| 86 | |
| 87 | | API | Host | Auth | Purpose | |
| 88 | |-----|------|------|---------| |
| 89 | | Gamma | `https://gamma-api.polymarket.com` | none | Events/markets/conditions/prices metadata | |
| 90 | | CLOB | `https://clob.polymarket.com` | EIP-712 | Order book, order placement/cancel | |
| 91 | | Data | `https://data-api.polymarket.com` | none | Historical trades | |
| 92 | | WebSocket | `wss://ws-subscriptions-clob.polymarket.com/ws/` | none (market) / JWT (user) | Real-time book + trade ticks | |
| 93 | |
| 94 | Chain: Polygon mainnet `chain_id=137`. Collateral: USDC.e at `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174`. |
| 95 | |
| 96 | --- |
| 97 | |
| 98 | ## WebSocket |
| 99 | |
| 100 | ```python |
| 101 | # Connect to: wss://ws-subscriptions-clob.polymarket.com/ws/market |
| 102 | # Subscribe message: |
| 103 | {"type": "market", "assets_ids": ["<token_id>", "<token_id2>"]} |
| 104 | ``` |
| 105 | |
| 106 | Event types: `book` (full snapshot on subscribe), `price_change` (delta updates), `last_trade_price`. |
| 107 | |
| 108 | For user-level order/fill events, connect to `/ws/user` with a JWT derived from your API credentials. |
| 109 | |
| 110 | --- |
| 111 | |
| 112 | ## On-chain settlement and redemption |
| 113 | |
| 114 | Polymarket weather markets resolve via **Weather Underground** ("History" tab), on the metro's **local clock with DST**, midnight-to-midnight. This differs from Kalshi, which uses LST (no DST) and NWS CLI — see `kalshi-weather-markets` for the divergence. |
| 115 | |
| 116 | After resolution, winning tokens **must be redeemed manually on-chain**: |
| 117 | |
| 118 | ```python |
| 119 | # Call CTF contract redeemPositions() — the SDK or direct web3.py call |
| 120 | # Winnings are NOT auto-swept |