Skip to main content

polyoxide_data/api/
rankings.rs

1use polyoxide_core::{HttpClient, QueryBuilder, Request};
2
3use crate::{
4    error::DataApiError,
5    types::{RankingEntry, RankingWindow},
6};
7
8/// Rankings namespace — `GET /volume` and `GET /profit` on
9/// `lb-api.polymarket.com`.
10///
11/// This is a **different service** from
12/// [`DataApi::leaderboard`](crate::DataApi::leaderboard), which calls
13/// `/v1/leaderboard` on the main Data API host and returns a different shape.
14/// This one ranks traders by all-time or windowed volume and profit.
15///
16/// # Stability
17///
18/// This host is **not covered by any published Polymarket OpenAPI spec**. It
19/// was verified live, but carries no documented compatibility guarantee —
20/// treat it as more likely to change without notice than the rest of this
21/// crate. The base URL is configurable via
22/// [`DataApiBuilder::rankings_base_url`](crate::DataApiBuilder::rankings_base_url).
23#[derive(Clone)]
24pub struct RankingsApi {
25    pub(crate) http_client: HttpClient,
26}
27
28impl RankingsApi {
29    /// Rank traders by traded volume (`GET /volume`).
30    pub fn volume(&self) -> RankingRequest {
31        RankingRequest {
32            request: Request::new(self.http_client.clone(), "/volume"),
33        }
34    }
35
36    /// Rank traders by realized profit (`GET /profit`).
37    pub fn profit(&self) -> RankingRequest {
38        RankingRequest {
39            request: Request::new(self.http_client.clone(), "/profit"),
40        }
41    }
42}
43
44/// Request builder for a rankings query.
45pub struct RankingRequest {
46    request: Request<Vec<RankingEntry>, DataApiError>,
47}
48
49impl RankingRequest {
50    /// Set the ranking window. An unrecognized value is rejected upstream with
51    /// `{"error": "invalid request"}`, which is why this is an enum.
52    pub fn window(mut self, window: RankingWindow) -> Self {
53        self.request = self.request.query("window", window);
54        self
55    }
56
57    /// Limit the number of ranked entries returned.
58    pub fn limit(mut self, limit: u32) -> Self {
59        self.request = self.request.query("limit", limit);
60        self
61    }
62
63    /// Execute the request.
64    pub async fn send(self) -> Result<Vec<RankingEntry>, DataApiError> {
65        self.request.send().await
66    }
67}