Native Polymarket tools for OpenClaw agents — 40 tools across Gamma, CLOB, Data APIs, and 4 WebSocket channels with automatic REST fallback.
40 native Polymarket tools for OpenClaw agents. 32 REST + 8 WebSocket. All read tools work without credentials. Trading tools require L2 auth. WebSocket tools connect lazily with automatic REST fallback.
These tools work immediately with zero configuration:
Discovery: poly_events, poly_markets, poly_search, poly_tags, poly_sports
Pricing: poly_prices, poly_book, poly_price_history, poly_last_trade, poly_tick_size
Analytics: poly_positions, poly_closed_positions, poly_trades, poly_leaderboard, poly_profile, poly_whale_activity, poly_holders, , , ,
, , , , , ,
poly_open_interestpoly_live_volumepoly_portfolio_valuepoly_markets_tradedpoly_server_timepoly_ws_subscribepoly_ws_unsubscribepoly_ws_statuspoly_ws_pricespoly_ws_bookpoly_ws_sports_livepoly_ws_crypto_prices# Add to ~/.openclaw/.env
PM_API_KEY=your-api-key-uuid
PM_SECRET=your-hmac-secret
PM_PASSPHRASE=your-passphrase
PM_ADDRESS=0xYourPolygonWalletAddress
Tools requiring L2 auth:
poly_place_order, poly_place_orders, poly_cancel_order, poly_cancel_all, poly_get_orders, poly_cancel_market_orders, poly_heartbeat, poly_get_order, poly_order_scoring, poly_balance, poly_ws_trades_live
Cross-service features (e.g. auto-posting a trade announcement to X after a successful order) live in a separate skill: cross-service. They are opt-in and off by default. This Polymarket skill works fully standalone — no X credentials or coupling required. See the cross-service skill for bridge options.
| Canonical | Aliases |
|---|---|
PM_API_KEY | POLYMARKET_API_KEY, POLY_API_KEY |
PM_SECRET | POLYMARKET_SECRET, POLY_SECRET |
PM_PASSPHRASE | POLYMARKET_PASSPHRASE, POLY_PASSPHRASE |
PM_ADDRESS | POLYMARKET_ADDRESS, POLY_ADDRESS |
Browse or look up Polymarket events. Supports single lookup by ID/slug and filtered listing with keyset pagination.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| event_id | string | No | — | Get single event by numeric ID |
| tag_id | string | No | — | Filter by tag/category ID (e.g. "21" = Crypto) |
| tag_slug | string | No | — | Filter by tag slug (alternative to tag_id) |
| slug | string | No | — | Event slug for exact lookup |
| active | boolean | No | — | true = active events only |
| closed | boolean | No | false | true = include closed events |
| featured | boolean | No | — | Filter by featured status |
| cyom | boolean | No | — | Filter Create Your Own Market events |
| volume_min | number | No | — | Minimum total volume (USDC) |
| liquidity_min | number | No | — | Minimum current liquidity (USDC) |
| start_date_min | string | No | — | ISO 8601 date filter |
| end_date_min | string | No | — | Events ending after this date |
| end_date_max | string | No | — | Events ending before this date |
| order | string | No | — | Sort: volume_24hr, volume, liquidity, start_date, end_date, competitive, closed_time |
| ascending | boolean | No | true | Sort direction |
| exclude_tag_id | string | No | — | Comma-separated tag IDs to exclude |
| recurrence | string | No | — | Filter by recurrence pattern |
| related_tags | boolean | No | — | Include events from related tags |
Browse or look up Polymarket markets. Supports single lookup by ID/slug and filtered listing.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| market_id | string | No | — | Get single market by numeric ID |
| slug | string | No | — | Get single market by slug |
| tag_id | string | No | — | Filter by tag/category ID |
| clob_token_ids | string | No | — | Comma-separated CLOB token IDs |
| condition_ids | string | No | — | Comma-separated condition IDs (hex) |
| closed | boolean | No | false | Include closed markets |
| liquidity_num_min | number | No | — | Min liquidity (USDC) |
| liquidity_num_max | number | No | — | Max liquidity (USDC) |
| volume_num_min | number | No | — | Min volume (USDC) |
| volume_num_max | number | No | — | Max volume (USDC) |
| start_date_min | string | No | — | Markets starting after this date |
| end_date_max | string | No | — | Markets ending before this date |
| order | string | No | — | Sort: volume_num, liquidity_num, start_date, end_date |
| ascending | boolean | No | true | Sort direction |
| sports_market_types | string | No | — | Comma-separated sports types (winner, spread, total) |
| game_id | string | No | — | Filter by game ID |
| include_tag | boolean | No | — | Include tag data in response |
| related_tags | boolean | No | — | Include related tag markets |
| limit |
Full-text search across events, markets, profiles, and tags.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| query | string | Yes | — | Search query |
| limit | integer | No | 10 | Max results per type (1-50) |
| events_status | string | No | active | "active", "closed", or "all" |
| search_tags | boolean | No | false | Include tags in results |
| search_profiles | boolean | No | false | Include profiles in results |
| sort | string | No | — | Sort field |
| ascending | boolean | No | true | Sort direction |
| exclude_tag_id | string | No | — | Comma-separated tag IDs to exclude |
Browse tag categories and relationships.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| mode | string | No | list | "list", "detail", or "related" |
| tag_id | string | Conditional | — | Required for "detail" and "related" |
Polymarket sports metadata and valid market types.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| include_market_types | boolean | No | false | Also fetch valid sports market types |
Get price, midpoint, and spread in a single call.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| token_id | string | Yes | — | CLOB token ID |
| token_ids | string | No | — | Comma-separated for batch |
| side | string | No | BUY | "BUY" or "SELL" |
Get order book depth (bids and asks).
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| token_id | string | Yes | — | CLOB token ID |
Historical price data with configurable intervals.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| token_id | string | Yes | — | CLOB token ID |
| interval | string | No | 1h | "1m", "1h", "6h", "1d", "1w", "all", "max" |
| fidelity | integer | No | 100 | Data points (1-1000) |
| start_ts | integer | No | — | Start Unix timestamp |
| end_ts | integer | No | — | End Unix timestamp |
Last trade execution price.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| token_id | string | Yes | — | CLOB token ID |
| token_ids | string | No | — | Comma-separated batch (max 500) |
Tick size and fee rate for a token.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| token_id | string | Yes | — | CLOB token ID |
Place a single order on Polymarket CLOB. (Optional cross-service behaviours — e.g. announce the trade to X — are handled by the cross-service skill when enabled.)
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| token_id | string | Yes | — | CLOB token ID |
| side | string | Yes | — | "BUY" or "SELL" |
| price | number | Yes | — | Limit price (0.01-0.99) |
| size | number | Yes | — | Number of shares |
| order_type | string | No | GTC | "GTC", "GTD", "FOK", "FAK" |
| expiration | integer | Conditional | — | Unix timestamp. Required for GTD |
| neg_risk | boolean | No | false | Required true for markets with 3+ outcomes |
| post_only | boolean | No | false | Reject if order would match immediately |
| tick_size | string | No | 0.01 | Precision: "0.1", "0.01", "0.001", "0.0001" |
Batch orders (max 15). Never auto-posts to X.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| orders | array | Yes | — | Array of order objects (same fields as poly_place_order) |
Cancel a single order by ID.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| order_id | string | Yes | — | Order ID to cancel |
Cancel ALL open orders across ALL markets.
No parameters required.
Cancel all orders for a specific market or asset.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| market | string | No | — | Market condition ID |
| asset_id | string | No | — | Token ID (more specific) |
List orders for the authenticated account.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| market | string | No | — | Filter by condition ID |
| asset_id | string | No | — | Filter by token ID |
| limit | integer | No | 50 | Results (1-500) |
| cursor | string | No | — | Pagination cursor |
Get a single order by ID.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| order_id | string | Yes | — | Order ID (hex hash) |
Prevent auto-cancellation of open orders. Send every 5 seconds.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| heartbeat_id | string | No | — | heartbeat_id from previous response |
Check if an order qualifies for maker rewards.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| order_id | string | Yes | — | Order ID to check |
Check USDC balance and token allowance.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| asset_type | string | No | USDC | "USDC" or "CONDITIONAL" |
| token_id | string | Conditional | — | Required if CONDITIONAL |
Get CLOB server time for clock sync. No parameters.
Current open positions for a wallet.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| address | string | No | PM_ADDRESS | Wallet address |
| market | string | No | — | Filter by condition ID |
| event_id | string | No | — | Filter by event ID |
| redeemable | boolean | No | — | Only redeemable positions |
| size_threshold | number | No | 1 | Min position size |
| mergeable | boolean | No | false | Mergeable positions only |
| title | string | No | — | Filter by market title |
| limit | integer | No | 100 | Results (1-500) |
| offset | integer | No | 0 | Pagination offset |
| sort_by | string | No | — | CURRENT, INITIAL, TOKENS, CASHPNL, PERCENTPNL, TITLE, RESOLVING, PRICE, AVGPRICE |
| sort_direction | string | No | DESC | "ASC" or "DESC" |
Closed/resolved positions with historical PnL.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| address | string | No | PM_ADDRESS | Wallet address |
| market | string | No | — | Filter by condition ID |
| event_id | string | No | — | Filter by event ID |
| limit | integer | No | 50 | Results (1-50) |
| offset | integer | No | 0 | Pagination offset |
| sort_by | string | No | — | REALIZEDPNL, TITLE, PRICE, AVGPRICE, TIMESTAMP |
| sort_direction | string | No | DESC | "ASC" or "DESC" |
Trade history with optional activity feed.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| address | string | No | PM_ADDRESS | Wallet address |
| market | string | No | — | Filter by condition ID |
| event_id | string | No | — | Filter by event ID |
| include_activity | boolean | No | false | Include splits, merges, redemptions |
| limit | integer | No | 50 | Results (1-500) |
| offset | integer | No | 0 | Pagination offset |
Top traders ranked by PnL or volume.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| category | string | No | OVERALL | OVERALL, CRYPTO, POLITICS, SPORTS, CULTURE, MENTIONS, WEATHER, ECONOMICS, TECH, FINANCE |
| period | string | No | ALL | DAY, WEEK, MONTH, ALL |
| order_by | string | No | PNL | PNL or VOL |
| limit | integer | No | 25 | Traders (1-50) |
| offset | integer | No | 0 | Pagination offset |
Public profile for a wallet address.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| address | string | No | PM_ADDRESS | Wallet address |
Track whale wallet activity for copy-trading signals.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| address | string | Yes | — | Whale wallet address |
| type | string | No | — | TRADE, SPLIT, MERGE, REDEEM, REWARD, CONVERSION, MAKER_REBATE, REFERRAL_REWARD |
| market | string | No | — | Filter by condition ID |
| side | string | No | — | BUY or SELL |
| start | integer | No | — | Unix timestamp min |
| end | integer | No | — | Unix timestamp max |
| limit | integer | No | 50 | Activities (1-500) |
| offset | integer | No | 0 | Pagination offset |
| sort_direction | string | No | DESC | "ASC" or "DESC" |
Top holders for a market.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| market | string | Yes | — | Market condition ID |
| limit | integer | No | 20 | Holders (1-20) |
| min_balance | number | No | — | Min position balance |
Open interest for markets.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| markets | string | Yes | — | Comma-separated condition IDs |
Live trading volume for an event.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| event_id | string | Yes | — | Gamma event ID |
Total portfolio value for a wallet.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| address | string | No | PM_ADDRESS | Wallet address |
Total number of markets a wallet has traded.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| address | string | No | PM_ADDRESS | Wallet address |
Subscribe to CLOB market data. Connects lazily on first call.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| token_ids | string | Yes | — | Comma-separated CLOB token IDs |
Remove tokens from the market feed.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| token_ids | string | Yes | — | Comma-separated CLOB token IDs |
Status of all 4 WebSocket channels + state store. No parameters.
Prices from WSS cache (instant) with REST fallback.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| token_id | string | Yes | — | CLOB token ID |
| token_ids | string | No | — | Comma-separated for batch |
| side | string | No | BUY | For REST fallback pricing |
Response source: "websocket" (instant), "rest" (API call), or "mixed".
Order book from WSS cache (instant) with REST fallback.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| token_id | string | Yes | — | CLOB token ID |
Live trade/order events from User WSS. Requires L2 auth.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| condition_ids | string | Yes | — | Comma-separated market condition IDs |
| event_types | string | No | all | "order", "trade", or "all" |
| limit | integer | No | 20 | Recent events (1-100) |
Live sports scores. Auto-connects on first call.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| slug | string | No | — | Filter by sport slug pattern |
| live_only | boolean | No | true | Only live games |
Crypto/equity prices from RTDS. Auto-subscribes on first call.
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
| topic | string | Yes | — | "crypto_prices", "crypto_prices_chainlink", or "equity_prices" |
| symbols | string | No | — | Comma-separated symbol filter |
| Variable | Default | Description |
|---|---|---|
PM_WS_ENABLED | true | Master toggle for all WSS connections |
PM_WS_INACTIVITY_TIMEOUT | 120 | Seconds before declaring WSS dead |
PM_WS_RECONNECT_MAX_DELAY | 60 | Max seconds between reconnects |
| Channel | URL | Auth | Heartbeat |
|---|---|---|---|
| CLOB Market | wss://ws-subscriptions-clob.polymarket.com/ws/market | None | Client PING 10s |
| CLOB User | wss://ws-subscriptions-clob.polymarket.com/ws/user | L2 | Client PING 10s |
| Sports | wss://sports-api.polymarket.com/ws | None | Server ping 5s |
| RTDS | wss://ws-live-data.polymarket.com | None | Client PING 5s |
All poly_ws_* tools transparently fall back to REST when WSS data is unavailable. Response source field indicates path used.
1. poly_search("bitcoin price") -> Find relevant markets
2. poly_events({ tag_id: "21" }) -> Browse crypto events
3. poly_prices({ token_id: "..." }) -> Check price + spread
4. poly_book({ token_id: "..." }) -> Verify liquidity depth
5. poly_tick_size({ token_id: "..." }) -> Get tick size + fee rate
6. poly_balance() -> Verify USDC balance
7. poly_place_order({ ... }) -> Execute trade
8. poly_positions() -> Confirm position
1. poly_ws_subscribe({ token_ids }) -> Start live feed
2. poly_ws_crypto_prices({ topic }) -> Monitor external prices
3. poly_ws_prices({ token_id }) -> Instant price from cache
4. poly_ws_book({ token_id }) -> Instant book from cache
5. poly_place_order({ ... }) -> Execute trade
6. poly_ws_trades_live({ condition_ids })-> Monitor fill status
7. poly_heartbeat({ heartbeat_id }) -> Keep orders alive
Polymarket and X are separate skills. Agents can call both sequentially whenever both are available in the environment. Example of using them together as an intel pipeline:
1. x_timeline(polymarket_user_id) -> @Polymarket announcements (X skill)
2. x_search("BTC breaking news") -> Gauge sentiment (X skill)
3. poly_search("bitcoin") -> Find markets (this skill)
4. poly_prices({ token_id }) -> Check pricing (this skill)
5. poly_place_order({ ... }) -> Trade on combined intel (this skill)
For server-side automation that links the two (e.g. auto-posting a trade to X after a successful order), see the cross-service skill. That's opt-in; this skill works standalone.
| API | Overall | Key Endpoints |
|---|---|---|
| Gamma | 4,000/10s | /events 500/10s, /markets 300/10s, /public-search 350/10s |
| CLOB | 9,000/10s | /book 1,500/10s, POST /order 3,500/10s, DELETE /order 3,000/10s |
| Data | 1,000/10s | /trades 200/10s, /positions 150/10s |
Built-in rate limiting prevents exceeding these limits by default.
| Category | Taker Fee | Maker Fee |
|---|---|---|
| Crypto | 0.072 | 0% |
| Sports | 0.03 | 0% |
| Finance, Politics, Tech, Mentions | 0.04 | 0% |
| Economics, Culture, Weather, Other | 0.05 | 0% |
| Geopolitics | 0% | 0% |
Read tools return empty results:
poly_search with a broad query firstTrading tools return 401:
PM_API_KEY, PM_SECRET, PM_PASSPHRASE, PM_ADDRESScurl http://127.0.0.1:8000/health for poly_l2 auth statusNeg risk markets fail:
neg_risk: true for markets with 3+ outcomesOrders auto-cancelled:
poly_heartbeat every 5 seconds with the heartbeat_id from the previous responseWebSocket not receiving data:
poly_ws_status for channel health| title_search | string | No | — | Search events by title |
| limit | integer | No | 20 | Results per page (1-100) |
| cursor | string | No | — | Keyset pagination cursor |
| integer |
| No |
| 20 |
| Results per page (1-100) |
| cursor | string | No | — | Keyset pagination cursor |