Fully typed Polymarket SDK for Python — Gamma, CLOB, Data API, WebSocket, and order placement
Project description
Polymarket SDK & Proxy Server
A fully typed SDK and proxy server built with Elysia for Polymarket APIs. This package provides standalone SDK clients, WebSocket real-time streaming, and a proxy server with type-safe endpoints for CLOB and Gamma APIs, featuring comprehensive validation and automatic OpenAPI schema generation. Available in TypeScript, Python, and Go.
Features
- Fully Typed SDK: Complete TypeScript support with no
anytypes - WebSocket Client: Real-time market data streaming with auto-reconnection
- Proxy Server: REST API with OpenAPI documentation
- MCP Server: Model Context Protocol server for AI interactions
- Type Safety: End-to-end type validation and transformation
- Multiple Runtimes: Supports Bun, Node.js, Deno, and Cloudflare Workers
- Multi-Language Support: TypeScript, Python, and Go clients with identical APIs
Motivation & Approach
- Reason: The official Polymarket SDKs in TypeScript and Python aren't fully typed; some return values are
unknown/any. - Solution: A fully typed SDK plus a translation proxy server with end-to-end type safety and OpenAPI.
- Codegen: Generate SDKs in other languages from the proxy server's OpenAPI schema.
- Transformations: The proxy doesn't always return exactly the same payload as the original API. It normalizes data by parsing and validating fields. For example, some endpoints return an array of strings as a JSON-stringified string; the proxy parses this into a proper typed array for easier consumption and validation.
- Status: Work in progress — not all APIs are included yet.
Architecture
This package provides two ways to use Polymarket APIs:
1. Standalone SDK Clients
PolymarketSDK: For CLOB operations (requires credentials) — TypeScriptGammaSDK: For Gamma API operations (no credentials required) — TypeScriptDataSDK: For user positions, trades, and activity data — TypeScriptPolymarketWebSocketClient: For real-time market data streaming — TypeScriptGammaClient: Gamma API client — PythonClobClient: CLOB price history client — PythonTradingClient: Order placement and management — PythonPolymarketWebSocket: Async WebSocket for market and user channels — PythonWebSocketClient: For real-time market data streaming — GoRedundantWSPool: Redundant parallel connections with message deduplication — Go
2. Proxy Server (Optional)
- Gamma API (
/gamma/*) - Market and event data fromgamma-api.polymarket.com - CLOB API (
/clob/*) - Trading and price history from Polymarket CLOB client - Data API (
/data/*) - User positions, trades, and activity data
Directory Structure
src/
├── mod.ts # Main SDK exports (JSR entry point)
├── index.ts # Elysia server entry point
├── client.ts # Proxy client (referenced in JSR)
├── run.ts # Server runner for development
├── sdk/ # Standalone SDK clients
│ ├── index.ts # SDK exports
│ ├── client.ts # PolymarketSDK (CLOB client)
│ ├── gamma-client.ts # GammaSDK (Gamma API client)
│ ├── data-client.ts # DataSDK (Data API client)
│ └── websocket-client.ts # WebSocket client for real-time data
├── routes/ # Elysia server routes
│ ├── gamma.ts # Gamma API endpoints
│ ├── clob.ts # CLOB API endpoints
│ └── data.ts # Data API endpoints
├── types/
│ ├── elysia-schemas.ts # Unified TypeBox schema definitions
│ └── websocket-schemas.ts # WebSocket message schemas (Zod)
└── utils/ # Utility functions
py-src/
└── polymarket_kit/
├── __init__.py # Package exports
├── profile.py # Wallet address extraction from usernames
├── gamma/ # Gamma API client (GammaClient, GammaSDK)
├── clob/ # CLOB client (ClobClient, TradingClient)
├── data/ # Data API client (DataSDK)
└── ws/ # Async WebSocket client (PolymarketWebSocket)
go-client/
├── auth/ # Ethereum wallet & signing
├── client/ # CLOB client implementation
│ ├── clob_client.go # Main API client
│ ├── websocket_client.go # Market WebSocket
│ ├── user_ws.go # User channel WebSocket
│ ├── orders.go # Order building & placement
│ ├── ws_pool.go # Redundant WebSocket pool
│ └── aggregator.go # Message deduplication
├── order/ # Order building utilities
├── realtime/ # Real-time data client
├── data/ # Data API client
├── gamma/ # Gamma API client
└── examples/ # Comprehensive usage examples
JSR Package Exports (from jsr.json)
.→./src/mod.ts- Main SDK exports./proxy→./src/client.ts- Proxy client./sdk→./src/sdk/index.ts- Direct SDK access
SDK Usage
TypeScript SDK
Using GammaSDK (No credentials required)
import { GammaSDK } from "@hk/polymarket";
const gammaSDK = new GammaSDK();
// Get all active markets
const markets = await gammaSDK.getActiveMarkets();
// Get markets with filtering
const filteredMarkets = await gammaSDK.getMarkets({
limit: "10",
active: "true",
volume_num_min: "1000",
});
// Get specific market by slug
const market = await gammaSDK.getMarketBySlug("bitcoin-above-100k");
// Get events with filtering
const events = await gammaSDK.getEvents({
limit: "5",
active: "true",
end_date_min: "2024-01-01",
});
Using PolymarketSDK (Requires credentials)
import { PolymarketSDK } from "@hk/polymarket";
const polymarketSDK = new PolymarketSDK({
privateKey: "your_private_key",
funderAddress: "your_funder_address",
});
// Get price history for a market
const priceHistory = await polymarketSDK.getPriceHistory({
market: "0x123...", // CLOB token ID
interval: "1h",
startDate: "2024-01-01",
endDate: "2024-01-31",
});
// Check CLOB connection health
const health = await polymarketSDK.healthCheck();
Python SDK
Installation
# Using uv (recommended)
uv add polymarket-kit
# Using pip
pip install polymarket-kit
Using GammaClient (No credentials required)
from polymarket_kit import GammaSDK
gamma = GammaSDK()
# Get markets
markets = gamma.get_markets(limit=10, active=True)
# Get events
events = gamma.get_events(limit=5, active=True)
# Get market by slug
market = gamma.get_market_by_slug("bitcoin-above-100k")
Using TradingClient (Order placement)
import asyncio
from polymarket_kit import TradingClient
async def main():
client = TradingClient(
private_key="your_private_key",
funder="your_funder_address",
)
# Initialize and derive API credentials
creds = await client.initialize()
# Place a GTC limit buy order
resp = await client.place_limit_order(
token_id="60487116984468020978247225474488676749601001829886755968952521846780452448915",
price=0.45,
size=10.0,
side="BUY",
)
print(f"Order placed: {resp.order_id}, status={resp.status}")
# Query open orders
open_orders = await client.get_open_orders()
# Cancel an order
await client.cancel_order(resp.order_id)
asyncio.run(main())
Python WebSocket (Market channel)
import asyncio
from polymarket_kit import PolymarketWebSocket
from polymarket_kit.ws import BookMessage, PriceChangeMessage, LastTradePriceMessage
async def main():
ws = PolymarketWebSocket("market")
ws.on_book = lambda msg: print(f"Book: bids={len(msg.bids)} asks={len(msg.asks)}")
ws.on_price_change = lambda msg: print(f"Price change: {len(msg.price_changes)} changes")
ws.on_last_trade = lambda msg: print(f"Trade: {msg.side} @ {msg.price}")
ws.on_connect = lambda: print("Connected!")
await ws.connect()
await ws.subscribe([
"60487116984468020978247225474488676749601001829886755968952521846780452448915"
])
await asyncio.Event().wait() # run forever
asyncio.run(main())
Python WebSocket (User channel)
import asyncio
from polymarket_kit import PolymarketWebSocket, ApiCreds
async def main():
creds = ApiCreds(
api_key="your_api_key",
secret="your_secret",
passphrase="your_passphrase",
)
ws = PolymarketWebSocket("user", api_creds=creds)
ws.on_order = lambda evt: print(f"Order event: {evt}")
ws.on_trade = lambda evt: print(f"Trade event: {evt}")
await ws.connect()
await asyncio.Event().wait()
asyncio.run(main())
WebSocket Real-Time Data
Stream real-time market data with automatic authentication, reconnection, and type-safe message handling.
TypeScript WebSocket Client
import { ClobClient } from "@polymarket/clob-client";
import { Wallet } from "@ethersproject/wallet";
import { PolymarketWebSocketClient } from "@hk/polymarket";
const signer = new Wallet(process.env.POLYMARKET_KEY!);
const clobClient = new ClobClient("https://clob.polymarket.com", 137, signer);
// Create WebSocket client with asset IDs to subscribe to
const ws = new PolymarketWebSocketClient(clobClient, {
assetIds: ["60487116984468020978247225474488676749601001829886755968952521846780452448915"],
autoReconnect: true,
debug: true,
});
// Register event handlers
ws.on({
onBook: (msg) => {
console.log(`Book Update - Bids: ${msg.bids.length}, Asks: ${msg.asks.length}`);
},
onPriceChange: (msg) => {
console.log(`Price Change - ${msg.price_changes.length} changes`);
},
onLastTradePrice: (msg) => {
console.log(`Trade: ${msg.side} @ ${msg.price}`);
},
onError: (error) => console.error("Error:", error),
onConnect: () => console.log("Connected!"),
});
await ws.connect();
Go WebSocket Client
import (
"github.com/HuakunShen/polymarket-kit/go-client/client"
"github.com/HuakunShen/polymarket-kit/go-client/types"
)
config := &client.ClientConfig{
Host: "https://clob.polymarket.com",
ChainID: types.ChainPolygon,
PrivateKey: os.Getenv("POLYMARKET_KEY"),
}
clobClient, _ := client.NewClobClient(config)
wsClient := client.NewWebSocketClient(clobClient, &client.WebSocketClientOptions{
AssetIDs: []string{
"60487116984468020978247225474488676749601001829886755968952521846780452448915",
},
AutoReconnect: true,
Debug: true,
})
wsClient.On(&client.WebSocketCallbacks{
OnBook: func(msg *types.BookMessage) {
fmt.Printf("Book Update - Bids: %d, Asks: %d\n", len(msg.Bids), len(msg.Asks))
},
OnLastTradePrice: func(msg *types.LastTradePriceMessage) {
fmt.Printf("Trade: %s @ %s\n", msg.Side, msg.Price)
},
OnError: func(err error) {
fmt.Printf("Error: %v\n", err)
},
})
wsClient.Connect()
Go Redundant WebSocket Pool
For high-availability scenarios, use RedundantWSPool which maintains N parallel connections with automatic message deduplication:
pool := client.NewRedundantWSPool(&client.PoolConfig{
Redundancy: 3, // 3 parallel connections
DedupTTL: 60 * time.Second,
OnMessage: func(msg []byte) {
// deduplicated message callback
fmt.Println(string(msg))
},
})
ctx := context.Background()
pool.Start(ctx)
pool.Subscribe([]string{"asset_id_1", "asset_id_2"})
WebSocket Features
- Automatic Authentication - Handles API key derivation automatically
- Type-Safe Messages - Full validation and typing for all message types
- Auto-Reconnection - Configurable reconnection with exponential backoff
- Event Handlers - Clean callback API for each message type
- User Channel - Authenticated order/trade event streaming (Python & Go)
- Redundant Pool - Multiple parallel connections with deduplication (Go)
- Debug Logging - Optional detailed logging for troubleshooting
Message Types
The WebSocket client handles these message types:
- Book Messages - Full orderbook snapshots and updates
- Price Change Messages - Real-time price level changes
- Tick Size Change Messages - Minimum tick size updates
- Last Trade Price Messages - Trade execution events
- Order Events - Order placement/fill events (user channel)
- Trade Events - Trade execution events (user channel)
See WebSocket Client Documentation for detailed API reference and examples.
Type Definitions
All types are exported from the unified schema:
import type {
// Market & Event Types
MarketType,
EventType,
MarketQueryType,
EventQueryType,
PriceHistoryQueryType,
PriceHistoryResponseType,
// WebSocket Types
MarketChannelMessage,
BookMessage,
PriceChangeMessage,
TickSizeChangeMessage,
LastTradePriceMessage,
WebSocketClientOptions,
WebSocketClientCallbacks,
} from "@hk/polymarket";
Proxy Server API Endpoints
System Endpoints
GET /- API information and available endpointsGET /health- Global health checkGET /docs- Swagger/OpenAPI documentation
Gamma API Endpoints
GET /gamma/markets- Get markets with comprehensive filtering- Query params:
limit,offset,order,ascending,id,slug,archived,active,closed,clob_token_ids,condition_ids,liquidity_num_min,liquidity_num_max,volume_num_min,volume_num_max,start_date_min,start_date_max,end_date_min,end_date_max,tag_id,related_tags
- Query params:
GET /gamma/events- Get events with comprehensive filtering- Query params:
limit,offset,order,ascending,id,slug,archived,active,closed,liquidity_min,liquidity_max,volume_min,volume_max,start_date_min,start_date_max,end_date_min,end_date_max,tag,tag_id,related_tags,tag_slug
- Query params:
CLOB API Endpoints
GET /clob/prices-history- Get price history for a market token- Required query param:
market(CLOB token ID) - Time range options:
startTs,endTs(Unix timestamps) ORstartDate,endDate(ISO strings) - Interval option:
interval(1m, 1h, 6h, 1d, 1w, max) - Data resolution:
fidelity(resolution in minutes) - Headers:
x-polymarket-key,x-polymarket-funder(required in production)
- Required query param:
GET /clob/health- CLOB client connection health checkGET /clob/cache/stats- Get cache statistics for SDK instances and CLOB clientsDELETE /clob/cache- Clear all caches
Data API Endpoints
GET /data/positions- Get user positionsGET /data/closed-positions- Get closed positionsGET /data/trades- Get user tradesGET /data/activity- Get user activityGET /data/holders- Get market holdersGET /data/top-holders- Get top holders for a marketGET /data/total-value- Get total portfolio valueGET /data/markets-traded- Get total markets traded countGET /data/open-interest- Get open interestGET /data/live-volume- Get live trading volumeGET /data/health- Data API health check
Installation & Setup
Python SDK
# Using uv
uv add polymarket-kit
# Using pip
pip install polymarket-kit
Requires Python >= 3.12.
TypeScript SDK
# Using Deno
deno add @hk/polymarket
# Using Bun
bunx jsr add @hk/polymarket
# Using npm
npx jsr add @hk/polymarket
Running the Proxy Server
-
Install dependencies:
bun install -
Environment Variables:
# Required for CLOB API endpoints POLYMARKET_KEY=your_private_key_here POLYMARKET_FUNDER=your_funder_address # Optional PORT=3000 # defaults to 3000 SDK_CACHE_MAX_SIZE=50 # defaults to 50 SDK_CACHE_TTL_HOURS=1 # defaults to 1 CLOB_CLIENT_CACHE_MAX_SIZE=100 # defaults to 100 CLOB_CLIENT_CACHE_TTL_MINUTES=30 # defaults to 30
-
Development:
bun run dev
-
Production:
bun run src/index.ts
-
Deploy to Cloudflare Workers (optional):
bun run deploy
OpenAPI Schema Generation
The server automatically generates OpenAPI 3.0 schemas that can be used to create type-safe SDKs for other languages.
Accessing the Schema
- Swagger UI: Visit
/docswhen the server is running - Raw JSON: Visit
/docs/jsonto get the OpenAPI JSON schema
Generating SDKs from OpenAPI Schema
# Install generator
npm install -g @openapitools/openapi-generator-cli
# Generate Python client
openapi-generator-cli generate \
-i http://localhost:3000/docs/json \
-g python \
-o ./generated/python-client \
--additional-properties=packageName=polymarket_proxy_client
# Generate Go client
openapi-generator-cli generate \
-i http://localhost:3000/docs/json \
-g go \
-o ./generated/go-client \
--additional-properties=packageName=polymarket
# Generate TypeScript client
openapi-generator-cli generate \
-i http://localhost:3000/docs/json \
-g typescript-axios \
-o ./generated/ts-client
Type Safety & Validation
TypeScript: Unified TypeBox Schema System
All types are defined in src/types/elysia-schemas.ts using TypeBox — a single source of truth for compile-time types, runtime validation, and OpenAPI generation.
// All schemas are defined once in elysia-schemas.ts
export const MarketSchema = t.Object({
id: t.String(),
question: t.String(),
// ... comprehensive type definitions
});
// Types are automatically derived
export type MarketType = typeof MarketSchema.static;
Python: Pydantic Models
All Python types are defined as Pydantic models, providing runtime validation and IDE auto-completion.
MCP Server
The Model Context Protocol (MCP) server provides a natural language interface to Polymarket data for AI models and assistants.
Starting the MCP Server
bun run src/mcp/polymarket.ts
Available Tools
- Market Analysis:
get_markets,get_market_by_id,get_market_by_slug - Event Management:
get_events,get_event_by_id,get_event_markdown - Search & Discovery:
search_polymarket,get_tags - Analytics:
get_market_trends,get_popular_markets
Integration with AI Clients
{
"mcpServers": {
"polymarket": {
"command": "bun",
"args": ["run", "path/to/polymarket-kit/src/mcp/polymarket.ts"]
}
}
}
See GEMINI.md for detailed usage examples and integration guides.
Development Plan
Phase 1: Core Implementation ✅
- Basic Elysia server setup
- Gamma API routes with full typing
- CLOB API routes with full typing
- Data API routes with full typing
- OpenAPI documentation generation
- CORS and error handling
- Unified TypeBox schema system
- Standalone SDK clients (TypeScript)
- Python SDK (GammaClient, ClobClient, TradingClient, WebSocket)
- JSR package publishing support
- Eliminated duplicate schemas
- Comprehensive caching system
Phase 2: Advanced Features ✅
- WebSocket support for real-time data (TypeScript, Python, Go)
- Type-safe WebSocket message schemas
- Auto-reconnection and error handling
- User channel WebSocket (authenticated order/trade events)
- Redundant WebSocket pool with message deduplication (Go)
- Order placement with EIP-712 signing (Python, Go)
- Profile wallet address extraction (Python)
Phase 3: In Progress
- Rate limiting and request throttling
- Authentication/API key management
- Monitoring and metrics collection
- Enhanced error recovery mechanisms
- Automated SDK generation pipeline
Contributing
- Follow the existing TypeScript patterns
- Ensure all endpoints have proper Elysia type validation
- Update OpenAPI documentation for new endpoints
- Test with both development and production builds
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file polymarket_kit-0.1.0.tar.gz.
File metadata
- Download URL: polymarket_kit-0.1.0.tar.gz
- Upload date:
- Size: 1.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b65a2c8a8204070c5fdd8c140658b96ef929f16246ff973f13ba731fd3104410
|
|
| MD5 |
c8e8ba5ef5e3ebff1c04b50fb43e1efe
|
|
| BLAKE2b-256 |
a6c2c6fc0b577584027244c741478152b572dc9c4614c799cda0dde96f3e302c
|
Provenance
The following attestation bundles were made for polymarket_kit-0.1.0.tar.gz:
Publisher:
py-publish.yml on HuakunShen/polymarket-kit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
polymarket_kit-0.1.0.tar.gz -
Subject digest:
b65a2c8a8204070c5fdd8c140658b96ef929f16246ff973f13ba731fd3104410 - Sigstore transparency entry: 1192112819
- Sigstore integration time:
-
Permalink:
HuakunShen/polymarket-kit@5643d2876d46887120a4b468a547181965cc1cd2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/HuakunShen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
py-publish.yml@5643d2876d46887120a4b468a547181965cc1cd2 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file polymarket_kit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: polymarket_kit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 31.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40ce75e1657d765599507192ad46d511d5cf541f26d19f5c657d092126f02d92
|
|
| MD5 |
cef9b97eee7e33877aa1c7cbca83e343
|
|
| BLAKE2b-256 |
dd192ef5b73fbed78145913ea7b4775bbe5e83af2327b26e468aad2167543aa9
|
Provenance
The following attestation bundles were made for polymarket_kit-0.1.0-py3-none-any.whl:
Publisher:
py-publish.yml on HuakunShen/polymarket-kit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
polymarket_kit-0.1.0-py3-none-any.whl -
Subject digest:
40ce75e1657d765599507192ad46d511d5cf541f26d19f5c657d092126f02d92 - Sigstore transparency entry: 1192112821
- Sigstore integration time:
-
Permalink:
HuakunShen/polymarket-kit@5643d2876d46887120a4b468a547181965cc1cd2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/HuakunShen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
py-publish.yml@5643d2876d46887120a4b468a547181965cc1cd2 -
Trigger Event:
workflow_dispatch
-
Statement type: