Skip to main content
This is the page to keep open during an incident.
Prerequisites: Authentication and Firms, participants and accounts — most entries below resolve to one of those two sections or to a limit on this page. Limits are enforced per firm, so every process sharing your Client ID shares one budget.
API reference: Rate limits · Stream error handling. Opens on the public documentation site in a new tab. Where it disagrees with this page, this page is authoritative for the partner surface.

Rate limits

If you are an IB, this differs. The ledger CSV limit is what your reporting work hits first and hardest, so size your export design against it before anything else — see Reporting pack. You also do not have FIX on the partner surface, so FIX session tiers do not apply to you whatever you have heard in a commercial conversation.
Every limit we can state is in this section, with its scope. This is the canonical source: other pages quote a limit where it is relevant to what they are doing, and any number you find elsewhere in this space should agree with the row here. If one does not, this section wins — tell us, because the other page is wrong. A limit without a scope is worse than no limit, because you size your fleet against it and then share it. Read the Scope column on every row before you size anything.

REST

Per-endpoint query limits

These sit below the firm-wide REST ceiling: you can be inside 100 req/sec and still be limited here.
Whether these per-endpoint budgets are per firm or per credential is not published.Size against the pessimistic reading — one shared budget per firm — until your integration lead confirms otherwise.
The legacy summary table states “0.5–60 req/min” for query endpoints. Nothing is documented at 0.5/min. The lowest real value is 6/min. If you built a 2-minute polling interval to respect a 0.5/min figure, you are throttling yourself for no reason.

gRPC

The scope of the 50,000 / 60 s stream message limit is not published.Do not plan a fan-out against it.
20 concurrent streams is correct; the “10-connection limit” on the legacy streaming page is a leftover. Both numbers appear on the same page today.Two consequences worth designing around: the balance-ledger stream is per-account and counts against the 20, so it cannot be run per participant, and passing an empty symbols list subscribes to every instrument, which collides with the 1000-per-stream cap. One partner ran 7,372 subscriptions before being told the cap and had to re-architect in production.
/institutional/introduction claims streaming has “No rate limiting concerns”. That contradicts the 100 msg/sec ingress cap above. There are rate limiting concerns.

The undocumented endpoint rung

There is a third rung below the firm and endpoint budgets above, and it was unknown even to our own support until a partner surfaced it. It returns a gRPC code 8 with the delay in the message:
Parse the retry after value from the message and wait at least that long. The rung name ("endpoint") tells you the budget you hit, so log the full string.
The per-endpoint gRPC budgets behind this rung are not published.Treat the message as the only source of the delay.

Transfers

The Transfer rate limit is being confirmed and we are not publishing a number.Three different figures are live in our own material today, including one that is a global ceiling shared across all partners rather than a per-firm budget. The difference matters: a shared ceiling means another partner’s traffic can throttle yours, and you cannot size around it.Until this is settled: serialize your transfers, retry on failure with backoff, and tell your integration lead your required transfer rate so it can be sized against the real value.

Not published yet

These are genuinely undocumented. They are listed here so you do not spend a day looking for them.
/trader-guide/order-management promises per-operation order, cancel and modify limits. Those limits do not exist on the rate-limits page. Do not build against them.
Retail limits (20 req/sec per API key) and institutional limits (100 req/sec per firm) sit on two unlabelled legacy pages, which reads as a 5× discrepancy. They are two different products. Yours is the institutional one — see Environments and endpoints.

Backoff

  1. On 429, honour Retry-After. It is on the response. Do not retry sooner.
  2. On gRPC code 8, use the retry after value in the message as your floor.
  3. Add jitter. Every process under your Client ID shares one budget, so a fixed backoff makes your fleet retry in lockstep and re-hit the limit together.
  4. Cap concurrency, do not just retry. The firm-wide REST budget is a one-minute average, so a burst that clears retries can still put you over the minute.
  5. Never re-mint a token in response to a rate limit. 429 and code 8 are not auth failures, and the token mint is itself a request.
  6. Never retry CreateVendorOrder with a new idempotency_key. A new key is a new order, not a retry. Recovery is a byte-identical resubmit with the same key — see Order lifecycle.
Global Rate Limit Exceeded does not arrive as an HTTP or gRPC error. It comes back as an execution-report rejection on your order flow, so your HTTP layer sees success. Handle it in your execution-report consumer, not in your retry middleware. See Error catalog.

Error catalog

If you are an IB, this differs. Two failures are IB-only. HTTP 400 naming the participant type on the administrative create path comes from a casing defect — see Naming and record requirements for the canonical casing per path. And onboarding that stalls with no error returned to you is a DCO clearing-member ID used where a DCM firm name belongs; quote all three identity strings when you report it.
A limit you hit above arrives as one of the strings below. Look the verbatim string up here before you retry. Several of these are not errors in your code, and three of them get worse if you retry naively. Match on the message string, not on the status code alone. PERMISSION_DENIED and 403 are each raised for several distinct causes — a missing scope grant, a missing x-participant-id, x-participant-id sent on a firm-scoped call, and a firm entitlement that is not in place — and the code alone does not tell you which.

Authentication and entitlements

Identity and headers

Rate-limit errors

Orders

Order outcome handling in full is on Order lifecycle.

Funding and cash movement

Streams and transport

KYC and provisioning

Reference data and reports

Platform

These are ours — open a ticket

Retrying will not fix any of these. Post in your shared Slack channel, tag the Polymarket side, and say whether it moves money.
  • 403 no ISV adapter found for ISV ID [VERIFY] — incomplete provisioning of your firm.
  • NOT_FOUND: customer relationship claim failed when your SSNs are distinct — an incomplete server-side setup step or a half-provisioned firm.
  • {"code": 9, "message": "user already provisioned with a different SSN"} — needs manual database cleanup by us.
  • {"code":12,"message":"unknown service connamara.ep3.v1beta1.KYCAPI"} — service not reachable.
  • 13 INTERNAL: Subscription manager revoked session — apply the explicit-market-list workaround, then report it.
  • ResourceExhausted … heap_pressure — a guard that is wrong in every environment.
  • decision: ACCEPT with status: CLOSED and an empty participantId — a bug.
  • HTTP 400 on the participant type — a casing defect on our side.

What can go wrong

The verbatim string for each of these, and for every other error on the ISV surface, is in Error catalog.

Next

KYC flow