polyoxide-data
Rust client library for the Polymarket Data API.
Read-only access to Polymarket user positions, trades, activity, holders, open interest, live volume, leaderboards, builder analytics, market-positions, and accounting snapshots. No authentication required.
More information about this crate can be found in the crate documentation.
Features
- Read-Only, No Auth: All endpoints are public -- no API keys or signing needed
- Fluent Builder Pattern: Chainable query parameters with
.send().await?
- Type-Safe Responses: Strongly-typed structs with serde deserialization
- Built-In Rate Limiting: Automatic rate limiting and concurrency control (default: 4 concurrent requests)
Installation
[dependencies]
polyoxide-data = "0.17"
Or use the unified client:
[dependencies]
polyoxide = "0.17"
Usage
Create a Client
use polyoxide_data::DataApi;
# fn doctest() -> Result<(), Box<dyn std::error::Error>> {
let data = DataApi::new()?;
let data = DataApi::builder()
.timeout_ms(30_000)
.pool_size(10)
.max_concurrent(8)
.build()?;
# let _ = data;
# Ok(())
# }
User Positions
# use polyoxide_data::DataApi;
use polyoxide_data::types::PositionSortBy;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let positions = data.user("0x1234...abcd")
.list_positions()
.limit(10)
.sort_by(PositionSortBy::CashPnl)
.send()
.await?;
for pos in positions {
println!("{}: size={} pnl={}", pos.title, pos.size, pos.cash_pnl);
}
# Ok(())
# }
User Position Value
# use polyoxide_data::DataApi;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let values = data.user("0x1234...abcd")
.positions_value()
.send()
.await?;
for v in values {
println!("Total value: {}", v.value);
}
# Ok(())
# }
Closed Positions
# use polyoxide_data::DataApi;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let closed = data.user("0x1234...abcd")
.closed_positions()
.limit(5)
.send()
.await?;
for pos in closed {
println!("{}: realized P&L = {}", pos.title, pos.realized_pnl);
}
# Ok(())
# }
User Trades
# use polyoxide_data::DataApi;
use polyoxide_data::types::TradeSide;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let trades = data.user("0x1234...abcd")
.trades()
.side(TradeSide::Buy)
.limit(20)
.send()
.await?;
for trade in trades {
println!("{} {} @ {}", trade.title, trade.size, trade.price);
}
# Ok(())
# }
User Activity
# use polyoxide_data::DataApi;
use polyoxide_data::types::ActivityType;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let activity = data.user("0x1234...abcd")
.activity()
.activity_type([ActivityType::Trade, ActivityType::Redeem])
.limit(50)
.send()
.await?;
for a in activity {
println!("{:?}: {} USDC", a.activity_type, a.usdc_size);
}
# Ok(())
# }
Markets Traded Count
# use polyoxide_data::DataApi;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let traded = data.user("0x1234...abcd").traded().await?;
println!("Total markets traded: {}", traded.traded);
# Ok(())
# }
Global Trades
# use polyoxide_data::DataApi;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let trades = data.trades()
.list()
.limit(10)
.send()
.await?;
for trade in trades {
println!("{}: {} @ {}", trade.title, trade.size, trade.price);
}
# Ok(())
# }
Top Holders
# use polyoxide_data::DataApi;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let holders = data.holders()
.list(["condition_id_1", "condition_id_2"])
.limit(50)
.min_balance(100)
.send()
.await?;
for market in holders {
println!("Token {}: {} holders", market.token, market.holders.len());
}
# Ok(())
# }
Open Interest
# use polyoxide_data::DataApi;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let oi = data.open_interest()
.get()
.market(["condition_id_here"])
.send()
.await?;
for entry in oi {
println!("{}: {}", entry.market, entry.value);
}
# Ok(())
# }
Live Volume
# use polyoxide_data::DataApi;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let volumes = data.live_volume().get(12345).await?;
for vol in volumes {
println!("Total volume: {}", vol.total);
}
# Ok(())
# }
Trader Leaderboard
# use polyoxide_data::DataApi;
use polyoxide_data::api::leaderboard::{LeaderboardCategory, LeaderboardOrderBy};
use polyoxide_data::types::TimePeriod;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let rankings = data.leaderboard()
.get()
.category(LeaderboardCategory::Politics)
.time_period(TimePeriod::Week)
.order_by(LeaderboardOrderBy::Pnl)
.limit(10)
.send()
.await?;
for trader in rankings {
println!("#{} {} - PnL: {}", trader.rank, trader.proxy_wallet, trader.pnl);
}
# Ok(())
# }
Builder Leaderboard
# use polyoxide_data::DataApi;
use polyoxide_data::types::TimePeriod;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let rankings = data.builders()
.leaderboard()
.time_period(TimePeriod::Week)
.limit(10)
.send()
.await?;
for b in rankings {
println!("#{} {} - volume: {}", b.rank, b.builder, b.volume);
}
# Ok(())
# }
Builder Volume Time Series
# use polyoxide_data::DataApi;
use polyoxide_data::types::TimePeriod;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let volumes = data.builders()
.volume()
.time_period(TimePeriod::Month)
.send()
.await?;
for entry in volumes {
println!("{}: {} - volume {}", entry.dt, entry.builder, entry.volume);
}
# Ok(())
# }
Health Check
# use polyoxide_data::DataApi;
# async fn doctest() -> Result<(), Box<dyn std::error::Error>> {
# let data = DataApi::builder().build()?;
let health = data.health().check().await?;
println!("Status: {}", health.data);
let latency = data.health().ping().await?;
println!("API latency: {}ms", latency.as_millis());
# Ok(())
# }
API Namespaces
| Namespace |
Access |
Description |
data.user(addr) |
.list_positions(), .positions_value(), .closed_positions(), .trades(), .activity(), .traded() |
Per-user positions, trades, and activity |
data.trades() |
.list() |
Global trade history with filtering |
data.holders() |
.list(markets) |
Top token holders per market |
data.open_interest() |
.get() |
Market open interest |
data.live_volume() |
.get(event_id) |
Real-time event volume |
data.leaderboard() |
.get() |
Trader rankings by PnL or volume |
data.builders() |
.leaderboard(), .volume() |
Builder analytics and rankings |
data.market_positions() |
.list(market) |
Aggregated positions for a market |
data.accounting() |
.snapshot(addr) |
Accounting snapshot (ZIP bytes) |
data.health() |
.check(), .ping() |
API health and latency |
License
Licensed under either of MIT or Apache-2.0 at your option.