All posts
API ReferencePolymarket APIRate LimitsCLOB

Polymarket API Rate Limits: The Complete Reference

Polymarket publishes its rate limits across several pages, in two completely different systems, using a 10-second window almost nobody expects. This is all of it in one table set — plus what actually happens when you cross a limit.

11 min read

If you have ever tried to answer a simple question — how many requests per second can I send to Polymarket? — you will have discovered that there is no simple answer. The limits are spread across two separate systems, published on different pages, and expressed in a 10-second window rather than the per-second or per-minute figures most APIs use.

This page collects every documented limit in one place, explains the two systems, and shows what actually happens when you cross a line. All figures come from Polymarket's official documentation and are current as of September 2026.

Two different rate limit systems

This is the part that catches most developers out. Polymarket runs two independent limiters, and being under one does not protect you from the other.

Cloudflare IP limitsPer-signer token buckets
Scoped toYour IP addressYour signer address
Applies toEvery API and endpointCLOB order + cancel requests only
MechanismSliding windowToken bucket (refill rate + burst)
Over the limitRequests are throttled — delayed and queuedRequest is rejected with 429
Varies byEndpointYour 30-day trading volume tier
The two limiters are cumulative. Read-heavy bots usually only meet the first; trading bots meet both.

Gamma API rate limits

Base URL https://gamma-api.polymarket.com. Gamma serves market and event metadata — the endpoints most people hit first when they are exploring the platform.

EndpointLimitPer second
General4,000 req / 10s400 rps
/events500 req / 10s50 rps
/markets300 req / 10s30 rps
/markets + /events listing900 req / 10s90 rps
/comments200 req / 10s20 rps
/tags200 req / 10s20 rps
/public-search350 req / 10s35 rps

Data API rate limits

Base URL https://data-api.polymarket.com. Positions, trade history and portfolio data. Note how much tighter this API is than Gamma or CLOB — the general limit is 1,000 req / 10s, a quarter of Gamma's.

EndpointLimitPer second
General1,000 req / 10s100 rps
/trades200 req / 10s20 rps
/positions150 req / 10s15 rps
/closed-positions150 req / 10s15 rps
Health check (/ok)100 req / 10s10 rps

CLOB API rate limits

Base URL https://clob.polymarket.com. The order book itself. CLOB has the highest general allowance of any Polymarket API (9,000 req / 10s) but splits into four distinct groups with very different limits.

General

EndpointLimitPer second
General9,000 req / 10s900 rps
GET balance allowance200 req / 10s20 rps
UPDATE balance allowance50 req / 10s5 rps

Market data

The pattern to notice here: singular endpoints get 1,500 req / 10s, plural batch endpoints get 500 req / 10s. That looks like a downgrade until you remember one batch call covers many tokens. Batching is 3× cheaper per request but each call does far more work — always prefer /books over a loop of /book.

EndpointLimitPer second
/book1,500 req / 10s150 rps
/books500 req / 10s50 rps
/price1,500 req / 10s150 rps
/prices500 req / 10s50 rps
/midpoint1,500 req / 10s150 rps
/midpoints500 req / 10s50 rps
/prices-history1,000 req / 10s100 rps
Market tick size200 req / 10s20 rps

Ledger

EndpointLimitPer second
/trades, /orders, /notifications, /order900 req / 10s90 rps
/data/orders500 req / 10s50 rps
/data/trades500 req / 10s50 rps
/notifications125 req / 10s12.5 rps

Authentication

EndpointLimitPer second
API key endpoints100 req / 10s10 rps

Trading — burst and sustained

Trading endpoints are the only ones with two Cloudflare limits: a burst limit for short spikes and a sustained limit measured over 10 minutes. You must stay under both.

EndpointBurstSustained
POST /order5,000 req / 10s120,000 req / 10 min
DELETE /order5,000 req / 10s120,000 req / 10 min
POST /orders2,000 req / 10s21,000 req / 10 min
DELETE /orders2,000 req / 10s15,000 req / 10 min
DELETE /cancel-all250 req / 10s6,000 req / 10 min
DELETE /cancel-market-orders1,500 req / 10s21,000 req / 10 min

DELETE /cancel-all at 250 req / 10s is worth flagging. Market makers who cancel-all on every re-quote cycle burn through this quickly, and the sustained limit of 6,000 per 10 minutes works out to just 10 cancel-all calls per second on average.

Bridge, Relayer and everything else

EndpointLimit
General rate limiting (global ceiling)15,000 req / 10s
Health check (/ok)100 req / 10s
Bridge API (https://bridge.polymarket.com)50 req / 10s
Relayer /submit25 req / 1 min
User PNL API200 req / 10s

Per-signer token buckets (CLOB trading)

Separately from Cloudflare, Polymarket evaluates CLOB order and cancel requests against per-signer token buckets. Each signer address gets an order bucket and a cancel bucket; spending from one does not affect the other. Unlike the Cloudflare layer, exceeding these returns a real 429.

Requests cost tokens rather than counting as one unit each:

BucketRequestToken cost
OrderPOST /order1
OrderPOST /ordersNumber of orders in the batch
CancelDELETE /order1
CancelDELETE /ordersNumber of submitted order IDs
CancelDELETE /cancel-all1 + number of orders actually canceled
CancelDELETE /cancel-market-orders1 + number of matching orders canceled

Volume tiers

Your bucket size depends on the maker wallet's cumulative volume over a rolling 30-day window. Tier assignments refresh every three hours.

Tier30-day volumeOrder rate/sOrder burstCancel rate/sCancel burst
Standard406080120
Copper$30,000+6090120180
Bronze$50,000+80120160240
Silver$100,000+200300400600
Gold$500,000+4006008001,200
Platinum$2.5M+4506759001,350
Diamond$5M+5257871,0501,575
Elite$10M+6009001,2001,800
Standard, Copper, Bronze, Silver and Gold tiers allow a negative cancel balance; Platinum, Diamond and Elite floor it at zero.

Work out how long a full burst lasts with burst_seconds = burst / rate_per_sec. For a Standard signer that is 60 / 401.5 seconds of full-speed order submission before you are limited to the 40/s refill rate.

Reading the rate limit headers

The per-signer limiter returns headers on every evaluated request. These are the cheapest possible way to monitor your budget — no extra API calls needed.

HeaderMeaning
Poly-RateLimit-RemainingToken balance in the applicable bucket after this request
Poly-RateLimit-ResetUnix timestamp when the current wait period ends
Poly-RateLimit-TierWhich tier was applied
Retry-AfterRetry delay in seconds — only on 429 responses
Poly-RateLimit-Warningtrue when live enforcement would have rejected the request

Handling 429s properly

The correct retry strategy differs depending on which limiter you hit, and getting it wrong makes things worse. Respect Retry-After when it is present; fall back to exponential backoff with jitter when it is not. Jitter matters: without it, every one of your workers retries at the same instant and you re-trigger the limit immediately.

const MAX_RETRIES = 5;

async function polyFetch(url: string, init?: RequestInit): Promise<Response> {
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
    const res = await fetch(url, init);

    // Watch the budget even on success — this is your early warning.
    const remaining = res.headers.get("Poly-RateLimit-Remaining");
    if (remaining !== null && Number(remaining) < 10) {
      console.warn(`Low token budget: ${remaining} (tier ${res.headers.get("Poly-RateLimit-Tier")})`);
    }

    // Warning mode: not rejected yet, but it would have been.
    if (res.headers.get("Poly-RateLimit-Warning") === "true") {
      console.warn("Request would be rejected under live enforcement — slow down.");
    }

    if (res.status !== 429) return res;
    if (attempt === MAX_RETRIES) return res;

    // Prefer the server's own answer, else exponential backoff.
    const retryAfter = res.headers.get("Retry-After");
    const baseMs = retryAfter
      ? Number(retryAfter) * 1000
      : Math.min(2 ** attempt * 250, 8000);

    // Full jitter — spreads a fleet of workers out instead of resynchronising them.
    await new Promise((r) => setTimeout(r, Math.random() * baseMs));
  }

  throw new Error("unreachable");
}

Staying under the limits by design

  • Batch instead of looping. One /books call instead of fifty /book calls costs you one request against a 500 req/10s budget rather than fifty against a 1,500 req/10s budget — a 17× improvement in headroom.
  • Cache metadata. Market metadata from /markets barely changes within a market's life, but /markets has the tightest Gamma limit at 300 req/10s. Fetch once, cache, and stop re-requesting it in your hot loop.
  • Use WebSockets for live state. Polling /book on a timer is the most common way to burn a request budget. Subscribe to the stream instead and let the server push changes.
  • Add jitter to scheduled jobs. If every worker wakes on the exact minute, you create a synchronised spike well above your average rate. Randomise start offsets.
  • Watch latency, not just error rates. Because Cloudflare throttles rather than rejects, rising p99 latency is your first signal that you are over an IP limit — long before anything shows up as an error.
  • Track the headers. Poly-RateLimit-Remaining costs nothing to read and tells you exactly how much budget is left.

Rate limits are not the same as data access

One last thing worth being explicit about, because it is the most common misconception we see: no rate limit tier gives you historical order book depth. Polymarket's API serves the current state of the book. It does not expose a historical archive of what the book looked like at 14:03:17 last Tuesday, and once a market resolves it disappears from the public feeds entirely.

That is a structural gap rather than a throttling problem, and no amount of backoff logic solves it. If you are trying to backtest a strategy, you need point-in-time snapshots that somebody recorded at the time — which is exactly what PolyTest exists to provide: 90M+ historical snapshots of Polymarket crypto Up/Down markets with full order book depth, sub-second resolution, and no gaps.

PlanRequests / minBurst / secHistory
Free302Recent markets
Builder2501214 days
Pro75040Full history
EnterpriseCustomCustomFull history + bulk export
PolyTest's own limits, for comparison. Check yours programmatically with GET /api/v1/limits. See rate limits and pricing.

Frequently asked questions

What is the Polymarket API rate limit in requests per second?
Polymarket publishes limits per 10-second window, so divide by 10. The global ceiling is 15,000 req / 10s (1,500 rps), but per-endpoint limits are much lower and they are the binding constraint: CLOB /book and /price allow 1,500 req / 10s (150 rps), the Gamma /markets endpoint allows just 300 req / 10s (30 rps), and the Data API /positions endpoint allows 150 req / 10s (15 rps).
Does Polymarket return a 429 when you exceed the rate limit?
It depends which limiter you hit. The Cloudflare IP-based limits throttle requests — they are delayed and queued rather than rejected — so you see rising latency instead of errors. The separate per-signer token buckets on CLOB order and cancel endpoints do return 429 Too Many Requests, along with a Retry-After header telling you the minimum delay before retrying.
What are the Polymarket CLOB API rate limits?
The CLOB general limit is 9,000 req / 10s. Market data endpoints /book, /price and /midpoint allow 1,500 req / 10s each, while their batch equivalents /books, /prices and /midpoints allow 500 req / 10s. Ledger endpoints allow 900 req / 10s. Trading endpoints have both burst and sustained limits: POST /order allows 5,000 req / 10s burst and 120,000 req / 10 min sustained.
What are the Polymarket Gamma API rate limits?
The Gamma API general limit is 4,000 req / 10s. Individual endpoints are tighter: /events is 500 req / 10s, /markets is 300 req / 10s, combined /markets + /events listing is 900 req / 10s, /public-search is 350 req / 10s, and /comments and /tags are 200 req / 10s each. The /markets limit is the tightest commonly-used limit on the platform.
Are Polymarket rate limits per IP address or per API key?
The main Cloudflare limits are per IP address, not per API key, so multiple keys behind one IP share a single budget. The separate token-bucket limits on CLOB order and cancel endpoints are scoped to your signer address and sized by your maker wallet's 30-day trading volume tier.
Can I get historical Polymarket order book data through the API?
No. Polymarket's API serves current market state only — there is no historical order book depth archive, and resolved markets disappear from the public feeds. Backtesting requires point-in-time snapshots recorded as markets ran. PolyTest provides 90M+ such snapshots for Polymarket crypto Up/Down markets with full 8-level order book depth and sub-second resolution.

Get the historical data Polymarket does not keep

PolyTest records Polymarket crypto Up/Down markets as they run — 90M+ snapshots with 8 levels of order book depth, sub-second timestamps, and resolved markets preserved. Free tier, no card.

Keep reading