Overview
The Polymarket Rust SDK (polymarket-client-sdk) provides a high-performance client for the Polymarket CLOB (Central Limit Order Book) API. Built on top of the alloy Ethereum toolkit, the SDK handles EIP-712 signature generation, order building, and all HTTP communication with the CLOB endpoints. It is purpose-built for latency-sensitive trading applications where runtime overhead matters — market making bots, automated hedging agents, and high-frequency prediction market strategies.
This reference covers every major surface of the SDK: installation, client initialization, market data retrieval, order lifecycle management, position tracking, and Rust-specific error handling patterns.
Installation
Add the SDK and its required dependencies to your Cargo.toml:
# Cargo.toml
[dependencies]
polymarket-client-sdk = "0.1"
alloy = { version = "0.1", features = ["full"] }
tokio = { version = "1", features = ["full"] }
You can also add the crate from the command line:
cargo add polymarket-client-sdk
cargo add alloy --features full
cargo add tokio --features full
Requirements:
- Rust 1.70+ (the SDK uses recent stable features)
- OpenSSL development headers (for TLS on Linux:
apt install libssl-dev) - A funded Polygon wallet with a known private key or a proxy wallet address
After adding the dependencies, run cargo build to verify everything compiles. The alloy crate handles all low-level Ethereum primitives — key management, ABI encoding, and EIP-712 typed data signing — so you do not need additional signing libraries.
Client Initialization
The ClobClient is the main entry point for all SDK operations. Use the builder pattern to configure the host, chain ID, signing key, and wallet type:
use polymarket_client_sdk::ClobClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = ClobClient::builder()
.host("https://clob.polymarket.com")
.chain_id(137)
.private_key("YOUR_PRIVATE_KEY")
.signature_type(2) // GNOSIS_SAFE
.funder("YOUR_PROXY_WALLET_ADDRESS")
.build()
.await?;
println!("Client initialized on chain {}", client.chain_id());
Ok(())
}
Builder Parameters
| Parameter | Type | Description |
|---|---|---|
host | &str | CLOB API base URL. Use https://clob.polymarket.com for production. |
chain_id | u64 | Polygon mainnet is 137. Mumbai testnet is 80001. |
private_key | &str | Hex-encoded private key (with or without 0x prefix). |
signature_type | u8 | Wallet type: 0 = EOA, 1 = POLY_PROXY, 2 = GNOSIS_SAFE. |
funder | &str | Required for proxy wallets. The address that funds orders. |
Signature Types
0(EOA): Direct externally owned account. Use when trading from the key’s own address.1(POLY_PROXY): Polymarket proxy wallet for Magic Link (email login) users only.2(GNOSIS_SAFE): Gnosis Safe proxy wallet. Most common type — deployed automatically when you connect a wallet to Polymarket.com.
If you are unsure which signature type to use, start with 2 (GNOSIS_SAFE) — it covers the majority of Polymarket accounts. Use 1 (POLY_PROXY) only if you signed up via Magic Link email login, or 0 (EOA) if you generated the key yourself and never used the Polymarket web app.
Authentication
Deriving API Credentials
Before placing orders, you need API credentials (key, secret, passphrase) derived from your wallet signature. The SDK handles the signing automatically:
let creds = client.create_or_derive_api_creds().await?;
println!("API Key: {}", creds.api_key);
println!("Secret: {}", creds.api_secret);
println!("Passphrase: {}", creds.api_passphrase);
This method performs a one-time signature to derive deterministic credentials tied to your wallet. The credentials do not expire but can be regenerated at any time by calling create_or_derive_api_creds() again.
Setting API Credentials Directly
If you have previously derived credentials and stored them, you can set them directly on the client to avoid the derivation step:
let client = ClobClient::builder()
.host("https://clob.polymarket.com")
.chain_id(137)
.private_key("YOUR_PRIVATE_KEY")
.signature_type(1)
.funder("YOUR_PROXY_WALLET_ADDRESS")
.api_key("your-api-key")
.api_secret("your-api-secret")
.api_passphrase("your-api-passphrase")
.build()
.await?;
Store credentials securely. Do not commit them to version control or embed them in client-side code.
Market Data Methods
Market data methods are read-only and do not require API credentials. They are useful for price feeds, monitoring spreads, and building order books.
get_price
Returns the current best price for a given token on a specified side.
let price = client.get_price("TOKEN_ID", Side::Buy).await?;
println!("Best bid: {}", price);
Parameters:
token_id: &str— The conditional token ID.side: Side—Side::Buyfor the best bid,Side::Sellfor the best ask.
Returns: f64 — The current best price on the requested side.
get_midpoint
Returns the midpoint between the best bid and best ask.
let mid = client.get_midpoint("TOKEN_ID").await?;
println!("Midpoint: {}", mid);
Parameters:
token_id: &str— The conditional token ID.
Returns: f64 — The midpoint price. Useful as a fair-value estimate for market making.
get_order_book
Retrieves the full order book for a token.
let book = client.get_order_book("TOKEN_ID").await?;
println!("Bids: {:?}", book.bids);
println!("Asks: {:?}", book.asks);
println!("Spread: {:.4}", book.spread());
Parameters:
token_id: &str— The conditional token ID.
Returns: An OrderBook struct containing bids and asks as vectors of (price, size) tuples sorted by price.
get_tick_size
Returns the minimum price increment for a market.
let tick = client.get_tick_size("CONDITION_ID").await?;
println!("Tick size: {}", tick);
Parameters:
condition_id: &str— The condition ID (not the token ID).
Returns: f64 — The tick size. Polymarket markets use 0.01, 0.001, or 0.0001 depending on the market.
Ensure your order prices are aligned to the tick size. Orders submitted at invalid price increments will be rejected by the CLOB.
Order Placement
create_order
Builds and signs an order locally without submitting it. Useful when you need to inspect the signed payload or submit it later.
use polymarket_client_sdk::{OrderArgs, Side, OrderType};
let args = OrderArgs {
token_id: "TOKEN_ID".to_string(),
price: 0.65,
size: 50.0,
side: Side::Buy,
..Default::default()
};
let signed_order = client.create_order(args, OrderType::GTC).await?;
println!("Signed order: {:?}", signed_order);
post_order
Submits a previously signed order to the CLOB.
let result = client.post_order(&signed_order, OrderType::GTC).await?;
println!("Order ID: {}", result.order_id);
create_and_post_order
Combines create_order and post_order into a single call. This is the most common method for order submission:
use polymarket_client_sdk::{OrderArgs, Side, OrderType};
let order = OrderArgs {
token_id: "TOKEN_ID".to_string(),
price: 0.65,
size: 50.0,
side: Side::Buy,
..Default::default()
};
let result = client.create_and_post_order(order, OrderType::GTC).await?;
println!("Order ID: {}", result.order_id);
Order Types
| Type | Description |
|---|---|
OrderType::GTC | Good Til Cancelled. Rests on the book until filled or cancelled. |
OrderType::FOK | Fill or Kill. Must fill entirely or be rejected. |
OrderType::GTD | Good Til Date. Expires at a specified timestamp. |
Batch Operations
For placing multiple orders efficiently (e.g., building both sides of a market making spread), use the batch methods:
let prices = vec![0.60, 0.61, 0.62, 0.63, 0.64];
let token_id = "TOKEN_ID".to_string();
let orders: Vec<OrderArgs> = prices.iter().map(|&price| OrderArgs {
token_id: token_id.clone(),
price,
size: 50.0,
side: Side::Buy,
..Default::default()
}).collect();
let signed = client.create_orders(&orders).await?;
client.post_orders(&signed, OrderType::GTC).await?;
Batch operations sign all orders locally and then submit them in a single HTTP request. This reduces network round trips and improves fill rates for time-sensitive strategies.
Order Management
cancel_order
Cancels a single resting order by its order ID.
let cancelled = client.cancel_order("ORDER_ID").await?;
println!("Cancelled: {}", cancelled);
Parameters:
order_id: &str— The ID returned when the order was placed.
cancel_all
Cancels all open orders. Useful for emergency risk management or strategy shutdown:
let result = client.cancel_all().await?;
println!("Cancelled {} orders", result.cancelled_count);
This method cancels every resting order associated with your API credentials. It does not discriminate by market or token. Use it when you need to flatten your entire order set quickly.
Position Tracking
get_trades
Retrieves your historical fills and executions.
let trades = client.get_trades().await?;
for trade in &trades {
println!(
"Trade: {} {} @ {} ({})",
trade.side, trade.size, trade.price, trade.token_id
);
}
You can filter trades by market or time range by passing optional query parameters.
get_orders
Retrieves your open and historical orders.
let orders = client.get_orders().await?;
for order in &orders {
println!(
"Order {}: {} {} @ {} — status: {}",
order.id, order.side, order.size, order.price, order.status
);
}
get_positions
Retrieves your current open positions across all markets.
let positions = client.get_positions().await?;
for pos in &positions {
println!(
"Position in {}: size={}, avg_price={}",
pos.token_id, pos.size, pos.avg_price
);
}
Combine get_positions with get_price to calculate unrealized P&L in real time.
Error Handling
The SDK returns Result types for all fallible operations. Error variants cover the most common failure modes: authentication, rate limiting, order validation, and network issues.
use polymarket_client_sdk::Error;
use std::time::Duration;
match client.create_and_post_order(order, OrderType::GTC).await {
Ok(result) => println!("Order placed: {}", result.order_id),
Err(Error::RateLimit(retry_after)) => {
tokio::time::sleep(Duration::from_secs(retry_after)).await;
// Retry...
}
Err(Error::Auth(msg)) => eprintln!("Auth error: {}", msg),
Err(Error::Validation(msg)) => eprintln!("Invalid order: {}", msg),
Err(e) => eprintln!("Unexpected error: {}", e),
}
Common Error Variants
| Variant | Cause | Resolution |
|---|---|---|
Error::Auth | Invalid or expired API credentials. | Re-derive credentials with create_or_derive_api_creds(). |
Error::RateLimit | Too many requests. Includes a retry_after duration. | Back off and retry after the indicated interval. |
Error::Validation | Order parameters failed server-side validation (bad price, tick alignment, insufficient balance). | Check price alignment to tick size and account balance. |
Error::Network | Connection timeout or DNS resolution failure. | Retry with exponential backoff. |
Error::Api | Generic server error (500-level). | Retry after a brief delay. If persistent, check Polymarket status. |
Using the ? Operator
For simpler error propagation in async functions, use the ? operator with a boxed error return type:
async fn place_bid(client: &ClobClient, token_id: &str) -> Result<String, Box<dyn std::error::Error>> {
let order = OrderArgs {
token_id: token_id.to_string(),
price: 0.50,
size: 100.0,
side: Side::Buy,
..Default::default()
};
let result = client.create_and_post_order(order, OrderType::GTC).await?;
Ok(result.order_id)
}
Performance Notes
The Rust SDK is the highest-performance option available for interacting with the Polymarket CLOB API. Key advantages for latency-sensitive applications:
- No garbage collector pauses. Rust uses compile-time memory management through ownership and borrowing. There are no stop-the-world GC events that could delay order submission at critical moments.
- Zero-cost abstractions. The builder pattern, iterators, and async/await compile down to the same machine code you would write by hand. There is no runtime overhead from the SDK’s ergonomic API.
- Async runtime. Built on
tokio, the SDK uses non-blocking I/O for all network calls. You can run hundreds of concurrent market data streams or order submissions on a single thread. - Compile-time safety. Type mismatches, missing fields, and incorrect enum variants are caught at compile time rather than at runtime. This eliminates an entire class of bugs that plague Python and JavaScript trading bots in production.
- Predictable latency. No JIT warmup, no interpreter overhead. Cold-start and steady-state latency are nearly identical.
The Rust SDK is ideal for market makers who need to update quotes across many markets in tight loops, for agents that hedge positions across multiple platforms, and for any strategy where microseconds of latency translate directly to edge.
For strategies where development speed matters more than execution speed, consider the Python SDK or the TypeScript SDK instead.
FAQ
How do I install the Polymarket Rust SDK?
Add polymarket-client-sdk to your Cargo.toml dependencies. The SDK uses alloy for Ethereum signing and requires Rust 1.70+. Run cargo add polymarket-client-sdk to install. You will also need alloy with the full feature flag and tokio for the async runtime.
Why use the Rust SDK instead of Python or TypeScript?
The Rust SDK provides zero-cost abstractions, compile-time safety, and significantly lower latency for high-frequency trading scenarios. It is ideal for market makers and latency-sensitive agents where microseconds matter. The absence of a garbage collector means no unexpected pauses during critical order submission windows.
How do I handle errors in the Polymarket Rust SDK?
The SDK returns Result types for all fallible operations. Use pattern matching or the ? operator to handle errors. Common error variants include Error::Auth for authentication failures, Error::RateLimit with a retry-after duration, and Error::Validation for order parameter issues. See the Error Handling section above for complete examples.
Does the Rust SDK support all the same methods as the Python SDK?
The Rust SDK covers the core CLOB API surface including market data, order placement, order management, and position tracking. Some convenience methods available in py_clob_client (such as simplified market search or event browsing) may not have direct Rust equivalents. For those use cases, you can call the REST endpoints directly using reqwest alongside the SDK.
See Also
- py_clob_client Reference — Python SDK equivalent
- Polymarket TypeScript SDK Reference — TypeScript SDK equivalent
- Polymarket API Guide — Full API reference
- Polymarket Auth Troubleshooting — Fix authentication errors
- Polymarket Rate Limits Guide — Rate limits and retry strategies
- Prediction Market API Reference — Cross-platform comparison
This guide is maintained by AgentBets.ai. Found an error or API change we missed? Let us know on Twitter.
Not financial advice. Built for builders.
