Expand description
Unofficial Rust SDK for the Polymarket US Retail API.
The crate exposes a typed async REST client and a managed WebSocket stream.
Requests to authenticated endpoints are signed with Ed25519 and carry the
X-PM-* headers automatically.
§Getting started
Public endpoints need no credentials:
use polymarket_us::PolymarketUsClient;
let client = PolymarketUsClient::builder().build()?;
let markets = client.markets().list().await?;
println!("{} markets", markets.markets.len());Authenticated endpoints read credentials from POLYMARKET_US_KEY_ID and
POLYMARKET_US_SECRET_KEY:
use polymarket_us::{PolymarketUsClient, UsAuth};
let client = PolymarketUsClient::builder()
.auth(UsAuth::from_env()?)
.build()?;
let balances = client.account().balances().await?;§Resources
Endpoints are grouped behind accessors on the client: PolymarketUsClient::markets,
PolymarketUsClient::events, PolymarketUsClient::orders,
PolymarketUsClient::account, PolymarketUsClient::portfolio, and
PolymarketUsClient::search.
§Retries
Idempotent requests (GET, DELETE) are retried with exponential backoff and
jitter, honouring a server-supplied Retry-After. POST is never retried
automatically, so a submitted order cannot be duplicated by the transport
layer. See RetryConfig.
§Streaming
The venue splits its WebSocket surface across two sockets, and the SDK mirrors that split rather than multiplexing them:
| Data | Endpoint | Client |
|---|---|---|
| Books, trades, best-bid/offer | wss://api.polymarket.us/v1/ws/markets | MarketStreamClient |
| Orders, positions, balances | wss://api.polymarket.us/v1/ws/private | PrivateStreamClient |
Each client maintains its connection with automatic reconnect, replaying its
subscriptions every time. Connections that go silent are torn down after
StreamConnectConfig::idle_timeout so a dead socket cannot stall the
stream indefinitely, and a keepalive ping keeps a quiet market from tripping
that check.
use polymarket_us::{MarketStreamClient, MarketSubscription};
let client = MarketStreamClient::new(None);
let mut stream = client
.connect(vec![MarketSubscription::market_data(["btc-100k-2025"])])
.await?;
while let Some(message) = stream.next().await {
println!("{:?}", message.kind);
}Re-exports§
pub use auth::UsAuth;pub use client::PolymarketUsClient;pub use client::PolymarketUsClientBuilder;pub use error::PolymarketUsError;pub use resources::AccountClient;pub use resources::EventsClient;pub use resources::MarketsClient;pub use resources::OrdersClient;pub use resources::PortfolioClient;pub use resources::SearchClient;pub use retry::RetryConfig;pub use stream::MarketStream;pub use stream::MarketStreamClient;pub use stream::MarketSubscription;pub use stream::PrivateStream;pub use stream::PrivateStreamClient;pub use stream::PrivateSubscription;pub use stream::ReconnectConfig;pub use stream::StreamConnectConfig;pub use stream::StreamControlEvent;pub use stream::StreamDataEvent;pub use stream::StreamEndpoint;pub use stream::StreamMessage;pub use stream::StreamMessageKind;pub use stream::Subscription;pub use stream::SubscriptionType;pub use types::MarketStatus;pub use types::OrderAction;pub use types::OrderSide;pub use types::OrderType;pub use types::TimeInForce;