API · 참고 자료

폴리마켓에는 서로 다른 두 호스트에 두 개의 실시간 시스템이 있습니다. CLOB WebSocket은 호가창과 내 주문 업데이트를 스트리밍하고, RTDS 피드는 실시간 가격 데이터(크립토, 주식)와 댓글을 스트리밍합니다. 이 둘을 혼동하는 것이 가장 흔한 실수입니다 - 이 문서는 정확한 엔드포인트, 하트비트, 올바른 재연결과 함께 이 둘을 명확히 구분합니다.

두 호스트
  • CLOB - wss://ws-subscriptions-clob.polymarket.com/ws/ · 채널 market(공개, 호가창), user(인증, 내 주문/체결), sports(스포츠 시장의 실시간 경기 상태), 그리고 rfq 게이트웨이 (실시간 Request-for-Quote 상태 - RFQ 섹션 참조).
  • RTDS - wss://ws-live-data.polymarket.com · 토픽 crypto_prices, crypto_prices_chainlink, equity_prices, comments.

CLOB market 채널 (인증 불필요)

하나 이상의 토큰 ID를 구독하고 호가창과 업데이트를 받습니다: 초기 book 스냅샷에 이어 price_change, tick_size_change, last_trade_price 이벤트를 받습니다. 자격 증명은 필요 없습니다.

import asyncio, json, websockets

async def stream(token_ids):
    url = "wss://ws-subscriptions-clob.polymarket.com/ws/market"
    async with websockets.connect(url, ping_interval=10) as ws:
        await ws.send(json.dumps({"assets_ids": token_ids, "type": "market"}))
        async for msg in ws:
            evt = json.loads(msg)
            print(evt.get("event_type"), evt)

asyncio.run(stream([TOKEN_ID]))
import WebSocket from "ws";
const ws = new WebSocket("wss://ws-subscriptions-clob.polymarket.com/ws/market");
ws.on("open", () => ws.send(JSON.stringify({ assets_ids: [TOKEN_ID], type: "market" })));
ws.on("message", (d) => console.log(JSON.parse(d)));

CLOB user 채널 (인증)

user 채널은 내 주문 생애주기(넣기, 체결, 취소)를 보고합니다. API 키/시크릿/패스프레이즈가 필요하며, 토큰 ID가 아니라 condition_id(시장)로 구독합니다. wss://ws-subscriptions-clob.polymarket.com/ws/user에 연결하고 구독 페이로드에 인증을 포함하세요:

await ws.send(json.dumps({
    "type": "user",
    "markets": [CONDITION_ID],          # subscribe by condition_id, not token_id
    "auth": {"apiKey": API_KEY, "secret": SECRET, "passphrase": PASSPHRASE},
}))
# events: "order" (placed/cancelled) and "trade" (your fills)

RTDS 가격 피드

별도의 호스트 - wss://ws-live-data.polymarket.com - 로, 호가창이 아니라 실시간 가격 데이터용입니다. 토픽을 구독하세요: crypto_prices(Binance), crypto_prices_chainlink(Chainlink 오라클), equity_prices, comments. 크립토/주식 예측 시장 봇의 기초 신호로 유용합니다.

하트비트 & 재연결

  • 하트비트 - 약 10초마다 PING을 보내면 서버가 PONG으로 응답합니다. 놓치면 연결이 끊깁니다.
  • 실시간 수정 - 열린 연결에서 토픽이나 에셋을 추가/제거할 수 있습니다. 구독을 변경하려고 재연결할 필요가 없습니다.
  • 올바른 재연결 - 연결이 끊기면, 증분 업데이트를 다시 신뢰하기 전에 REST 호가창 스냅샷을 다시 가져오세요(GET /book). 연결이 끊긴 동안 놓친 스트리밍 델타는 사라집니다. REST 스냅샷이 로컬 호가창을 다시 동기화합니다.

이 전체 패턴을 하나의 견고한 루프로 - 하트비트, 백오프를 적용한 재연결, 그리고 (재)연결마다 REST 재동기화:

import asyncio, json, time, requests, websockets

async def resilient_stream(token_id, on_event):
    url = "wss://ws-subscriptions-clob.polymarket.com/ws/market"
    backoff = 1
    while True:
        try:
            async with websockets.connect(url, ping_interval=10) as ws:
                # 1) REST snapshot first so the local book is correct before deltas
                book = requests.get("https://clob.polymarket.com/book",
                                    params={"token_id": token_id}).json()
                on_event({"event_type": "snapshot", "book": book})
                # 2) subscribe and stream
                await ws.send(json.dumps({"assets_ids": [token_id], "type": "market"}))
                backoff = 1                       # reset after a clean connect
                async for msg in ws:
                    on_event(json.loads(msg))
        except Exception as e:
            print("ws drop, resync in", backoff, "s:", e)
            await asyncio.sleep(backoff)
            backoff = min(backoff * 2, 30)        # exponential backoff, capped
호스트를 혼동하지 마세요. 호가창과 내 주문은 CLOB 호스트(ws-subscriptions-clob)에서 오고, 크립토/주식 가격과 댓글은 RTDS (ws-live-data)에서 옵니다. 이들은 서로 다른 페이로드를 가진 서로 다른 서비스입니다.

다음: CLOB REST 참고 자료 · 요청 한도 & 백오프 · 만들기: 봇에서 호가창 스트리밍.