nautechsystems/nautilus_trader · error

Polymarket public trades API reached the historical offset c

Error message

Polymarket public trades API reached the historical offset ceiling for condition {}; cannot guarantee complete start-anchored results, narrow the time window

What it means

The Polymarket public trades endpoint caps pagination at an offset ceiling (10,000). When a start-anchored backfill (start is set) stops because it hit TradeTickStop::VenueOffsetCeiling, the adapter cannot guarantee the fetched data covers all trades back to the requested start, so it fails instead of returning silently incomplete history.

Source

Thrown at crates/adapters/polymarket/src/http/data_api.rs:178

    type Stop = TradeTickStop;

    fn consume(&mut self, rows: Vec<DataApiTrade>) -> anyhow::Result<Option<Self::Stop>> {
        self.rows.extend(rows);
        let capped = self.start.is_none()
            && self.limit.is_some_and(|target| {
                count_matching_trades_within_end(&self.rows, &self.token_id, self.end) >= target
            });
        Ok(capped.then_some(TradeTickStop::CallerCapped))
    }

    fn finish(self, completion: &Completion<Self::Stop>) -> anyhow::Result<Self::Output> {
        if self.start.is_some()
            && matches!(
                completion,
                Completion::Stopped(TradeTickStop::VenueOffsetCeiling(_))
            )
        {
            anyhow::bail!(
                "Polymarket public trades API reached the historical offset ceiling for condition {}; cannot guarantee complete start-anchored results, narrow the time window",
                self.condition_id
            );
        }

        let start_secs = self
            .start
            .map(|value| (value.as_u64() / 1_000_000_000) as i64);
        let end_secs = self
            .end
            .map(|value| (value.as_u64() / 1_000_000_000) as i64);
        let mut trades = parse_trade_ticks(
            self.rows,
            self.instrument_id,
            &self.token_id,
            self.price_precision,
            self.size_precision,
        )?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Narrow the requested time window (raise start) so fewer than 10,000 trades fall within the range.
  2. Backfill history in multiple smaller windows, paginating between them, and stitch the results.
  3. If you do not need start-anchored completeness, omit start (end-anchored fetches are allowed to stop at the ceiling).
  4. Use an alternative data source (e.g. the Data API endpoint) for full deep history of high-volume markets.

Example fix

// before: one huge window hits the venue offset ceiling
let ticks = api.request_trade_ticks(Some(condition_id), Some(launch_ts), Some(now), None).await?;
// after: chunk the range into windows below the ceiling
for (s, e) in chunk_range(launch_ts, now, max_window) {
    let ticks = api.request_trade_ticks(Some(condition_id), Some(s), Some(e), None).await?;
    sink.extend(ticks);
}
Defensive patterns

Strategy: fallback

Validate before calling

// Rust: estimate trade count before requesting deep history
let approx_trades = market.avg_trades_per_day * days_since(start);
let needs_windowing = approx_trades > 10_000;

Try / catch

// Rust
match api.request_trade_ticks(Some(cid), Some(start), Some(end), None).await {
    Ok(ticks) => Ok(ticks),
    Err(e) if e.to_string().contains("offset ceiling") => windowed_backfill(&api, &cid, start, end).await,
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: request_trade_ticks with a start timestamp far enough in the past that more than MAX_OFFSET (10,000) worth of paginated trades exists for the condition; the pagination loop finishes with Completion::Stopped(TradeTickStop::VenueOffsetCeiling).

Common situations: Requesting full trade history for a very liquid market since inception; long historical backfills after long downtime; start anchored at epoch or market launch date on high-volume conditions.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/97aeb6ac72ccac9a. Report an issue: GitHub.