Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

11 Commits

Repository files navigation

Polymarket US Python SDK

Official Python SDK for the Polymarket US API.

Installation

pip install polymarket-us

Usage

Public Endpoints (No Authentication)

frompolymarket_usimportPolymarketUSclient=PolymarketUS()
# Get events with paginationevents=client.events.list({"limit": 10, "offset": 0, "active": True})
next_page=client.events.list({"limit": 10, "offset": 10, "active": True})
# Get a specific eventevent=client.events.retrieve(123)
event_by_slug=client.events.retrieve_by_slug("super-bowl-2025")
# Get marketsmarkets=client.markets.list()
market=client.markets.retrieve_by_slug("btc-100k")
# Get order bookbook=client.markets.book("btc-100k")
# Get best bid/offerbbo=client.markets.bbo("btc-100k")
# Searchresults=client.search.query({"query": "bitcoin"})
# Series and sportsseries=client.series.list()
sports=client.sports.list()

Authenticated Endpoints (Trading)

importosfrompolymarket_usimportPolymarketUSclient=PolymarketUS(
key_id=os.environ["POLYMARKET_KEY_ID"],
secret_key=os.environ["POLYMARKET_SECRET_KEY"],
)
# Create an orderorder=client.orders.create({
"marketSlug": "btc-100k-2025",
"intent": "ORDER_INTENT_BUY_LONG",
"type": "ORDER_TYPE_LIMIT",
"price": {"value": "0.55", "currency": "USD"},
"quantity": 100,
"tif": "TIME_IN_FORCE_GOOD_TILL_CANCEL",
})
# Get open ordersopen_orders=client.orders.list()
# Cancel an orderclient.orders.cancel(order["id"], {"marketSlug": "btc-100k-2025"})
# Cancel all ordersclient.orders.cancel_all()
# Get positionspositions=client.portfolio.positions()
# Get activity historyactivities=client.portfolio.activities()
# Get account balancesbalances=client.account.balances()
client.close()

Async Usage

importasyncioimportosfrompolymarket_usimportAsyncPolymarketUSasyncdefmain():
asyncwithAsyncPolymarketUS(
key_id=os.environ["POLYMARKET_KEY_ID"],
secret_key=os.environ["POLYMARKET_SECRET_KEY"],
) asclient:
# Concurrent requestsevents, markets=awaitasyncio.gather(
client.events.list({"limit": 10}),
client.markets.list({"limit": 10}),
)
print(f"Found {len(events['events'])} events")
print(f"Found {len(markets['markets'])} markets")
asyncio.run(main())

Authentication

Polymarket US uses Ed25519 signature authentication. Generate API keys at polymarket.us/developer.

The SDK automatically signs requests with your credentials:

client=PolymarketUS(
key_id="your-api-key-id", # UUIDsecret_key="your-secret-key", # Base64-encoded Ed25519 private key
)

Error Handling

frompolymarket_usimport (
PolymarketUS,
APIConnectionError,
APITimeoutError,
AuthenticationError,
BadRequestError,
NotFoundError,
RateLimitError,
)
try:
client.orders.create({...})
exceptAuthenticationErrorase:
print(f"Invalid credentials: {e.message}")
exceptBadRequestErrorase:
print(f"Invalid order parameters: {e.message}")
exceptRateLimitErrorase:
print(f"Rate limit exceeded: {e.message}")
exceptNotFoundErrorase:
print(f"Resource not found: {e.message}")
exceptAPITimeoutError:
print("Request timed out")
exceptAPIConnectionErrorase:
print(f"Connection error: {e.message}")

Configuration

client=PolymarketUS(
key_id="your-key-id",
secret_key="your-secret-key",
timeout=30.0, # Request timeout in seconds (default: 30.0)max_retries=2, # Automatic retries for idempotent requests (default: 2)
)

Retries & reliability

Idempotent requests (GET, DELETE) are retried automatically on transient failures — connection errors, timeouts, and 408/409/429/5xx responses — using exponential backoff with jitter. Non-idempotent requests such as order placement are never retried automatically, so a network blip cannot submit a duplicate order. Set max_retries=0 to disable retries.

Every request sends a User-Agent and a generated poly-correlation-id so failures can be traced. The correlation id is attached to raised errors:

frompolymarket_usimportAPIErrortry:
client.account.balances()
exceptAPIErrorase:
print(e.status_code, e.message, e.request_id)

WebSocket (Real-Time Data)

Note: WebSocket connections are async-only due to their event-driven nature. Use asyncio.run() when working with the sync client, or use AsyncPolymarketUS directly.

importasyncioimportosfrompolymarket_usimportPolymarketUSasyncdefmain():
client=PolymarketUS(
key_id=os.environ["POLYMARKET_KEY_ID"],
secret_key=os.environ["POLYMARKET_SECRET_KEY"],
)
# Private WebSocket (orders, positions, balances)private_ws=client.ws.private()
defon_order_snapshot(data):
print(f"Open orders: {data['orderSubscriptionSnapshot']['orders']}")
defon_order_update(data):
print(f"Order execution: {data['orderSubscriptionUpdate']['execution']}")
private_ws.on("order_snapshot", on_order_snapshot)
private_ws.on("order_update", on_order_update)
private_ws.on("error", lambdae: print(f"Error: {e}"))
awaitprivate_ws.connect()
awaitprivate_ws.subscribe("order-sub-1", "SUBSCRIPTION_TYPE_ORDER")
awaitprivate_ws.subscribe("pos-sub-1", "SUBSCRIPTION_TYPE_POSITION")
awaitprivate_ws.subscribe("balance-sub-1", "SUBSCRIPTION_TYPE_ACCOUNT_BALANCE")
# Markets WebSocket (order book, trades)markets_ws=client.ws.markets()
markets_ws.on("market_data", lambdad: print(f"Book: {d['marketData']}"))
markets_ws.on("trade", lambdad: print(f"Trade: {d['trade']}"))
awaitmarkets_ws.connect()
awaitmarkets_ws.subscribe("md-sub-1", "SUBSCRIPTION_TYPE_MARKET_DATA", ["btc-100k-2025"])
awaitmarkets_ws.subscribe("trade-sub-1", "SUBSCRIPTION_TYPE_TRADE", ["btc-100k-2025"])
# Keep runningawaitasyncio.sleep(60)
awaitprivate_ws.close()
awaitmarkets_ws.close()
asyncio.run(main())

API Reference

Events

MethodDescription
events.list(params?)List events with filtering
events.retrieve(id)Get event by ID
events.retrieve_by_slug(slug)Get event by slug

Markets

MethodDescription
markets.list(params?)List markets with filtering
markets.retrieve(id)Get market by ID
markets.retrieve_by_slug(slug)Get market by slug
markets.book(slug)Get order book
markets.bbo(slug)Get best bid/offer
markets.settlement(slug)Get settlement price

Orders (Authenticated)

MethodDescription
orders.create(params)Create a new order
orders.list(params?)Get open orders
orders.retrieve(order_id)Get order by ID
orders.cancel(order_id, params)Cancel an order
orders.modify(order_id, params)Modify an order
orders.cancel_all(params?)Cancel all open orders
orders.preview(params)Preview an order
orders.close_position(params)Close a position

Portfolio (Authenticated)

MethodDescription
portfolio.positions(params?)Get trading positions
portfolio.activities(params?)Get activity history

Account (Authenticated)

MethodDescription
account.balances()Get account balances

Series

MethodDescription
series.list(params?)List series
series.retrieve(id)Get series by ID

Sports

MethodDescription
sports.list()List sports
sports.teams(params?)Get teams for provider

Search

MethodDescription
search.query(params?)Search events (includes nested markets)

WebSocket (Authenticated, Async-Only)

MethodDescription
ws.private()Create private WebSocket connection
ws.markets()Create markets WebSocket connection

WebSocket methods (connect(), subscribe(), close()) are async and must be awaited.

Private WebSocket Events:

  • order_snapshot - Initial orders snapshot
  • order_update - Order execution updates
  • position_snapshot - Initial positions snapshot
  • position_update - Position changes
  • account_balance_snapshot - Initial balance
  • account_balance_update - Balance changes
  • heartbeat - Connection keepalive
  • error - Error events
  • close - Connection closed

Markets WebSocket Events:

  • market_data - Full order book updates
  • market_data_lite - Lightweight price data
  • trade - Trade notifications
  • heartbeat - Connection keepalive
  • error - Error events
  • close - Connection closed

Requirements

  • Python 3.10+

Development

# Install dev dependencies
pip install -e ".[dev]"# Run tests
pytest
# Run linting
ruff check .# Run type checking
mypy polymarket_us

License

MIT

About

Official Polymarket US Python SDK

Resources

Stars

29 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages