A unified Python interface for prediction market exchanges (Polymarket, Kalshi, Limitless, Opinion, and more).
Note: Use with a PMXT API key (hosted, recommended) or run a local PMXT service. Get a key at pmxt.dev/dashboard.
pip install pmxtRequirements: Python >= 3.8. The local PMXT service is bundled automatically via the pmxt-core dependency — only needed when self-hosting.
Get your API key at pmxt.dev/dashboard. For reads, only pmxt_api_key and wallet_address are required.
import pmxt
# Reads — pmxt_api_key + wallet_address only
client = pmxt.Polymarket(
pmxt_api_key="pmxt_live_...",
wallet_address="0xYourWalletAddress",
)
# Search for markets
markets = client.fetch_markets(query="Trump")
print(markets[0].title)
# Get outcome details
outcome = markets[0].outcomes[0]
print(f"{outcome.label}: {outcome.price * 100:.1f}%")
# Fetch historical data (use outcome.outcome_id!)
candles = client.fetch_ohlcv(
outcome.outcome_id,
resolution="1d",
limit=30,
)
# Get current order book
order_book = client.fetch_order_book(outcome.outcome_id)
spread = order_book.asks[0].price - order_book.bids[0].price
print(f"Spread: {spread * 100:.2f}%")
# Account reads
positions = client.fetch_positions()
balance = client.fetch_balance()When you pass pmxt_api_key, the SDK talks to the PMXT hosted services:
- Catalog requests go to
api.pmxt.dev(markets, events, order books, OHLCV, trades). - Trading requests go to
trade.pmxt.dev(orders, positions, balances). - The SDK does not spawn a local process.
- For Polymarket and Opinion, PMXT's PreFundedEscrow handles custody — you sign orders with your own key, PMXT settles on-chain.
When you omit pmxt_api_key, the Python SDK manages the local PMXT service for you:
- First API call: Checks if server is running
- Auto-start: Starts server if needed (takes ~1-2 seconds)
- Reuse: Multiple Python processes share the same server
- Zero config: Just import and use!
If you prefer to manage the server yourself:
# Disable auto-start
poly = pmxt.Polymarket(auto_start_server=False)
# Or start the server manually in a separate terminal
# $ pmxt-serverWith a PMXT API key, pass pmxt_api_key, wallet_address, and private_key. The SDK auto-wraps your key into an EIP-712 signer and PMXT settles the order on-chain.
import pmxt
trader = pmxt.Polymarket(
pmxt_api_key="pmxt_live_...",
wallet_address="0xYourWalletAddress",
private_key="0xYourPrivateKey",
)
balance = trader.fetch_balance()
print(f"Available: ${balance[0].available}")
order = trader.create_order(
market_id="market-uuid",
outcome_id="outcome-uuid",
side="buy",
order_type="market",
amount=5.0,
denom="usdc",
slippage_pct=30.0,
)
print(f"Order status: {order.status}")import pmxt
trader = pmxt.Opinion(
pmxt_api_key="pmxt_live_...",
wallet_address="0xYourWalletAddress",
private_key="0xYourPrivateKey",
)See the full hosted trading guide for venue support, custody model, and limits.
When self-hosting, you supply venue credentials directly — no pmxt_api_key. The SDK spawns a local PMXT service.
Requires your Polygon Private Key:
import os
import pmxt
poly = pmxt.Polymarket(
private_key=os.getenv("POLYMARKET_PRIVATE_KEY"),
proxy_address=os.getenv("POLYMARKET_PROXY_ADDRESS"), # Optional
# signature_type='gnosis-safe' (default)
)
# Check balance
balances = poly.fetch_balance()
print(f"Available: ${balances[0].available}")
# Place order (using outcome shorthand)
markets = poly.fetch_markets(query="Trump")
order = poly.create_order(
outcome=markets[0].yes,
side="buy",
type="limit",
amount=10,
price=0.55
)Requires API Key and Private Key:
import os
import pmxt
kalshi = pmxt.Kalshi(
api_key=os.getenv("KALSHI_API_KEY"),
private_key=os.getenv("KALSHI_PRIVATE_KEY"),
)
# Check positions
positions = kalshi.fetch_positions()
for pos in positions:
print(f"{pos.outcome_label}: ${pos.unrealized_pnl:.2f}")Requires Private Key:
import os
import pmxt
limitless = pmxt.Limitless(
private_key=os.getenv("LIMITLESS_PRIVATE_KEY")
)
# Check balance
balances = limitless.fetch_balance()
print(f"Available: ${balances[0].available}")fetch_markets(params?)- Get active markets# Fetch recent markets poly.fetch_markets(limit=20, sort='volume') # Search by text poly.fetch_markets(query='Fed rates', limit=10) # Fetch by slug/ticker poly.fetch_markets(slug='who-will-trump-nominate-as-fed-chair')
filter_markets(markets, query)- Filter markets by keywordfetch_ohlcv(outcome_id, params)- Get historical price candlesfetch_order_book(outcome_id)- Get current order bookfetch_trades(outcome_id, params)- Get trade historyget_execution_price(order_book, side, amount)- Get execution priceget_execution_price_detailed(order_book, side, amount)- Get detailed execution info
create_order(params)- Place a new ordercancel_order(order_id)- Cancel an open orderfetch_order(order_id)- Get order detailsfetch_open_orders(market_id?)- Get all open orders
fetch_balance()- Get account balancefetch_positions()- Get current positions
All methods return clean Python dataclasses:
@dataclass
class UnifiedMarket:
market_id: str # Use this for create_order
title: str
outcomes: List[MarketOutcome]
volume_24h: float
liquidity: float
url: str
# ... more fields
@dataclass
class MarketOutcome:
outcome_id: str # Use this for fetch_ohlcv/fetch_order_book/fetch_trades
label: str # "Trump", "Yes", etc.
price: float # 0.0 to 1.0 (probability)
# ... more fieldsSee the full API reference for complete documentation.
For deep-dive methods like fetch_ohlcv(), fetch_order_book(), and fetch_trades(), you must use the outcome ID, not the market ID:
markets = poly.fetch_markets(query="Trump")
outcome_id = markets[0].outcomes[0].outcome_id # Correct
candles = poly.fetch_ohlcv(outcome_id, ...) # Works
candles = poly.fetch_ohlcv(markets[0].market_id, ...) # Wrong!All prices represent probabilities (0.0 to 1.0). Multiply by 100 for percentages:
outcome = markets[0].outcomes[0]
print(f"Price: {outcome.price * 100:.1f}%") # "Price: 55.3%"from datetime import datetime
candle = candles[0]
dt = datetime.fromtimestamp(candle.timestamp / 1000)
print(dt)# Clone the repo
git clone https://github.com/pmxt-dev/pmxt.git
cd pmxt/sdks/python
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytestMIT