Update Polymarket documentation (2026-02-19)
- Added new documentation URLs from llms.txt index - Updated TARGET.md with 244 total documentation pages - Scraped new pages for trading, concepts, and API reference sections - Updated changelog and new index pages
This commit is contained in:
@@ -2,160 +2,180 @@
|
||||
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
|
||||
> Use this file to discover all available pages before exploring further.
|
||||
|
||||
# WSS Quickstart
|
||||
# Overview
|
||||
|
||||
The following code samples and explanation will show you how to subscribe to the Marker and User channels of the Websocket.
|
||||
You'll need your API keys to do this so we'll start with that.
|
||||
> Real-time market data and trading updates via WebSocket
|
||||
|
||||
## Getting your API Keys
|
||||
Polymarket provides WebSocket channels for near real-time streaming of orderbook data, trades, and personal order activity. There are four available channels: `market`, `user`, `sports`, and `RTDS` (Real-Time Data Socket).
|
||||
|
||||
<CodeGroup>
|
||||
```python DeriveAPIKeys-Python [expandable] theme={null}
|
||||
from py_clob_client.client import ClobClient
|
||||
## Channels
|
||||
|
||||
host: str = "https://clob.polymarket.com"
|
||||
key: str = "" #This is your Private Key. If using email login export from https://reveal.magic.link/polymarket otherwise export from your Web3 Application
|
||||
chain_id: int = 137 #No need to adjust this
|
||||
POLYMARKET_PROXY_ADDRESS: str = '' #This is the address you deposit/send USDC to to FUND your Polymarket account.
|
||||
| Channel | Endpoint | Auth |
|
||||
| ----------------------------------- | ------------------------------------------------------ | -------- |
|
||||
| Market | `wss://ws-subscriptions-clob.polymarket.com/ws/market` | No |
|
||||
| User | `wss://ws-subscriptions-clob.polymarket.com/ws/user` | Yes |
|
||||
| Sports | `wss://sports-api.polymarket.com/ws` | No |
|
||||
| [RTDS](/market-data/websocket/rtds) | `wss://ws-live-data.polymarket.com` | Optional |
|
||||
|
||||
#Select from the following 3 initialization options to matches your login method, and remove any unused lines so only one client is initialized.
|
||||
### Market Channel
|
||||
|
||||
### Initialization of a client using a Polymarket Proxy associated with an Email/Magic account. If you login with your email use this example.
|
||||
client = ClobClient(host, key=key, chain_id=chain_id, signature_type=1, funder=POLYMARKET_PROXY_ADDRESS)
|
||||
| Type | Description | Custom Feature |
|
||||
| ------------------ | ----------------------- | -------------- |
|
||||
| `book` | Full orderbook snapshot | No |
|
||||
| `price_change` | Price level updates | No |
|
||||
| `tick_size_change` | Tick size changes | No |
|
||||
| `last_trade_price` | Trade executions | No |
|
||||
| `best_bid_ask` | Best prices update | Yes |
|
||||
| `new_market` | New market created | Yes |
|
||||
| `market_resolved` | Market resolution | Yes |
|
||||
|
||||
### Initialization of a client using a Polymarket Proxy associated with a Browser Wallet(Metamask, Coinbase Wallet, etc)
|
||||
client = ClobClient(host, key=key, chain_id=chain_id, signature_type=2, funder=POLYMARKET_PROXY_ADDRESS)
|
||||
Types marked "Custom Feature" require `custom_feature_enabled: true` in your subscription.
|
||||
|
||||
### Initialization of a client that trades directly from an EOA.
|
||||
client = ClobClient(host, key=key, chain_id=chain_id)
|
||||
### User Channel
|
||||
|
||||
print( client.derive_api_key() )
|
||||
| Type | Description |
|
||||
| ------- | --------------------------------------------- |
|
||||
| `trade` | Trade lifecycle updates (MATCHED → CONFIRMED) |
|
||||
| `order` | Order placements, updates, and cancellations |
|
||||
|
||||
```
|
||||
### Sports
|
||||
|
||||
```javascript DeriveAPIKeys-TS [expandable] theme={null}
|
||||
//npm install @polymarket/clob-client
|
||||
//npm install ethers
|
||||
//Client initialization example and dumping API Keys
|
||||
import {ClobClient, ApiKeyCreds } from "@polymarket/clob-client";
|
||||
import { Wallet } from "@ethersproject/wallet";
|
||||
| Type | Description |
|
||||
| -------------- | ------------------------------------- |
|
||||
| `sport_result` | Live game scores, periods, and status |
|
||||
|
||||
const host = 'https://clob.polymarket.com';
|
||||
const signer = new Wallet("YourPrivateKey"); //This is your Private Key. If using email login export from https://reveal.magic.link/polymarket otherwise export from your Web3 Application
|
||||
## Subscribing
|
||||
|
||||
// Initialize the clob client
|
||||
// NOTE: the signer must be approved on the CTFExchange contract
|
||||
const clobClient = new ClobClient(host, 137, signer);
|
||||
Send a subscription message after connecting to specify which data you want to receive.
|
||||
|
||||
(async () => {
|
||||
const apiKey = await clobClient.deriveApiKey();
|
||||
console.log(apiKey);
|
||||
})();
|
||||
```
|
||||
</CodeGroup>
|
||||
### Market Channel
|
||||
|
||||
## Using those keys to connect to the Market or User Websocket
|
||||
```json theme={null}
|
||||
{
|
||||
"assets_ids": [
|
||||
"21742633143463906290569050155826241533067272736897614950488156847949938836455",
|
||||
"48331043336612883890938759509493159234755048973500640148014422747788308965732"
|
||||
],
|
||||
"type": "market",
|
||||
"custom_feature_enabled": true
|
||||
}
|
||||
```
|
||||
|
||||
<CodeGroup>
|
||||
```python WSS-Connection [expandable] theme={null}
|
||||
from websocket import WebSocketApp
|
||||
import json
|
||||
import time
|
||||
import threading
|
||||
| Field | Type | Description |
|
||||
| ------------------------ | --------- | ----------------------------------------------------------------- |
|
||||
| `assets_ids` | string\[] | Token IDs to subscribe to |
|
||||
| `type` | string | Channel identifier |
|
||||
| `custom_feature_enabled` | boolean | Enable `best_bid_ask`, `new_market`, and `market_resolved` events |
|
||||
|
||||
MARKET_CHANNEL = "market"
|
||||
USER_CHANNEL = "user"
|
||||
### User Channel
|
||||
|
||||
```json theme={null}
|
||||
{
|
||||
"auth": {
|
||||
"apiKey": "your-api-key",
|
||||
"secret": "your-api-secret",
|
||||
"passphrase": "your-passphrase"
|
||||
},
|
||||
"markets": ["0x1234...condition_id"],
|
||||
"type": "user"
|
||||
}
|
||||
```
|
||||
|
||||
class WebSocketOrderBook:
|
||||
def __init__(self, channel_type, url, data, auth, message_callback, verbose):
|
||||
self.channel_type = channel_type
|
||||
self.url = url
|
||||
self.data = data
|
||||
self.auth = auth
|
||||
self.message_callback = message_callback
|
||||
self.verbose = verbose
|
||||
furl = url + "/ws/" + channel_type
|
||||
self.ws = WebSocketApp(
|
||||
furl,
|
||||
on_message=self.on_message,
|
||||
on_error=self.on_error,
|
||||
on_close=self.on_close,
|
||||
on_open=self.on_open,
|
||||
)
|
||||
self.orderbooks = {}
|
||||
<Note>
|
||||
The `auth` fields (`apiKey`, `secret`, `passphrase`) are **only required for
|
||||
the user channel**. For the market channel, these fields are optional and can
|
||||
be omitted.
|
||||
</Note>
|
||||
|
||||
def on_message(self, ws, message):
|
||||
print(message)
|
||||
pass
|
||||
| Field | Type | Description |
|
||||
| --------- | --------- | -------------------------------------------------- |
|
||||
| `auth` | object | API credentials (`apiKey`, `secret`, `passphrase`) |
|
||||
| `markets` | string\[] | Condition IDs to receive events for |
|
||||
| `type` | string | Channel identifier |
|
||||
|
||||
def on_error(self, ws, error):
|
||||
print("Error: ", error)
|
||||
exit(1)
|
||||
<Note>
|
||||
The user channel subscribes by **condition IDs** (market identifiers), not
|
||||
asset IDs. Each market has one condition ID but two asset IDs (Yes and No
|
||||
tokens).
|
||||
</Note>
|
||||
|
||||
def on_close(self, ws, close_status_code, close_msg):
|
||||
print("closing")
|
||||
exit(0)
|
||||
### Sports Channel
|
||||
|
||||
def on_open(self, ws):
|
||||
if self.channel_type == MARKET_CHANNEL:
|
||||
ws.send(json.dumps({"assets_ids": self.data, "type": MARKET_CHANNEL}))
|
||||
elif self.channel_type == USER_CHANNEL and self.auth:
|
||||
ws.send(
|
||||
json.dumps(
|
||||
{"markets": self.data, "type": USER_CHANNEL, "auth": self.auth}
|
||||
)
|
||||
)
|
||||
else:
|
||||
exit(1)
|
||||
No subscription message required. Connect and start receiving data for all active sports events.
|
||||
|
||||
thr = threading.Thread(target=self.ping, args=(ws,))
|
||||
thr.start()
|
||||
## Dynamic Subscription
|
||||
|
||||
Modify subscriptions without reconnecting.
|
||||
|
||||
def subscribe_to_tokens_ids(self, assets_ids):
|
||||
if self.channel_type == MARKET_CHANNEL:
|
||||
self.ws.send(json.dumps({"assets_ids": assets_ids, "operation": "subscribe"}))
|
||||
### Subscribe to more assets
|
||||
|
||||
def unsubscribe_to_tokens_ids(self, assets_ids):
|
||||
if self.channel_type == MARKET_CHANNEL:
|
||||
self.ws.send(json.dumps({"assets_ids": assets_ids, "operation": "unsubscribe"}))
|
||||
```json theme={null}
|
||||
{
|
||||
"assets_ids": ["new_asset_id_1", "new_asset_id_2"],
|
||||
"operation": "subscribe",
|
||||
"custom_feature_enabled": true
|
||||
}
|
||||
```
|
||||
|
||||
### Unsubscribe from assets
|
||||
|
||||
def ping(self, ws):
|
||||
while True:
|
||||
ws.send("PING")
|
||||
time.sleep(10)
|
||||
```json theme={null}
|
||||
{
|
||||
"assets_ids": ["asset_id_to_remove"],
|
||||
"operation": "unsubscribe"
|
||||
}
|
||||
```
|
||||
|
||||
def run(self):
|
||||
self.ws.run_forever()
|
||||
For the user channel, use `markets` instead of `assets_ids`:
|
||||
|
||||
```json theme={null}
|
||||
{
|
||||
"markets": ["0x1234...condition_id"],
|
||||
"operation": "subscribe"
|
||||
}
|
||||
```
|
||||
|
||||
if __name__ == "__main__":
|
||||
url = "wss://ws-subscriptions-clob.polymarket.com"
|
||||
#Complete these by exporting them from your initialized client.
|
||||
api_key = ""
|
||||
api_secret = ""
|
||||
api_passphrase = ""
|
||||
## Heartbeats
|
||||
|
||||
asset_ids = [
|
||||
"109681959945973300464568698402968596289258214226684818748321941747028805721376",
|
||||
]
|
||||
condition_ids = [] # no really need to filter by this one
|
||||
### Market & User Channels
|
||||
|
||||
auth = {"apiKey": api_key, "secret": api_secret, "passphrase": api_passphrase}
|
||||
Send `PING` every 10 seconds. The server responds with `PONG`.
|
||||
|
||||
market_connection = WebSocketOrderBook(
|
||||
MARKET_CHANNEL, url, asset_ids, auth, None, True
|
||||
)
|
||||
user_connection = WebSocketOrderBook(
|
||||
USER_CHANNEL, url, condition_ids, auth, None, True
|
||||
)
|
||||
```
|
||||
PING
|
||||
```
|
||||
|
||||
market_connection.subscribe_to_tokens_ids(["123"])
|
||||
# market_connection.unsubscribe_to_tokens_ids(["123"])
|
||||
### Sports Channel
|
||||
|
||||
market_connection.run()
|
||||
# user_connection.run()
|
||||
```
|
||||
</CodeGroup>
|
||||
The server sends `ping` every 5 seconds. Respond with `pong` within 10 seconds.
|
||||
|
||||
```
|
||||
pong
|
||||
```
|
||||
|
||||
<Warning>
|
||||
If you don't respond to the server's ping within 10 seconds, the connection
|
||||
will be closed.
|
||||
</Warning>
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<Accordion title="Connection closes immediately after opening">
|
||||
Send a valid subscription message immediately after connecting. The server may
|
||||
close connections that don't subscribe within a timeout period.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Connection drops after ~10 seconds">
|
||||
You're not sending heartbeats. Send `PING` every 10 seconds for market/user
|
||||
channels, or respond to server `ping` with `pong` for the sports channel.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Not receiving any messages">
|
||||
1. Verify your asset IDs or condition IDs are correct 2. Check that the
|
||||
markets are active (not resolved) 3. Set `custom_feature_enabled: true` if
|
||||
expecting `best_bid_ask`, `new_market`, or `market_resolved` events
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Authentication failed (user channel)">
|
||||
Verify your API credentials are correct and haven't expired.
|
||||
</Accordion>
|
||||
|
||||
Reference in New Issue
Block a user