Skip to main content
Preprod runs the production API surface against a different liquidity source and a different resolution path, so some of your test flows cannot complete there at all. Read the fidelity matrix before you put a milestone behind one of them, then size your harness against the fixtures that actually exist.
Prerequisites: preprod credentials and a preprod keypair (Authentication), both of your firm names (Firms, participants and accounts), and — for the test harness — a funded preprod pool. Preprod access does not require a signed agreement. One partner lost roughly three weeks believing it did.

What preprod does and does not simulate

Fidelity matrix

The endpoints themselves: The gRPC hostname form is grpc-api.{env}.polymarketexchange.com. The form grpc-preprod.polymarketexchange.com appears on the current /trader-guide/environments page and is wrong; it has been wrong since the correction in changelog v0.0.25 on 2026-04-17 missed that page.
There are three environments — dev, preprod and production — and you build against preprod and production. Dev is not part of the partner path. If you were given a third set of credentials, confirm what it is with your integration lead before you point a test suite at it.

Liquidity: what is actually on the book

pmsim is the live liquidity provider in preprod. Symbol coverage is thin and uneven: roughly 48% of astatc- symbols, 3.7% of aec- symbols and 0.1% of aec-atp symbols carry any LP presence at all. Coverage is per environment; production liquidity comes from market makers and does not follow these numbers. Depth, where it exists, sits at the edges of the book. Of 121 open ATP instruments in one sweep, only a small minority showed any resting depth, and those showed it at prices like a 0.98offeranda0.98 offer and a 0.06 bid. Books also go empty for minutes at a time.

Why a thin book blocks you completely and does not affect market makers

CreateVendorOrder accepts TIME_IN_FORCE_FILL_OR_KILL and nothing else, so you are structurally always the taker and can only consume resting depth. With no resting depth there is nothing to take, and your order comes back EXPIRED — an FOK that never crossed, which is not a rejection and carries no reason by design. Market makers are unaffected because they post the resting depth rather than taking it, which is why “preprod is fine” and “preprod is unusable” are both true statements from different partners. The practical consequence: you cannot produce a fill on demand in preprod, so you cannot deterministically test anything downstream of a fill. See Test harness for the workarounds that exist.

Resolution: markets do not resolve

No market resolves in preprod. Instruments reach INSTRUMENT_STATE_EXPIRED in large batches — 363, 455, 544 and 549 instruments in a single observed session — with none resolving to an outcome. One partner asked six times over 40 days to be able to test a settlement flow and never could. If your plan includes a preprod settlement test, it does not currently work; raise it in Slack as a resolution request against a specific market you already hold rather than waiting for one to resolve on its own. atpcq is absent from the preprod resolution config, so it will not resolve even if a resolution is run for you.

Non-parity items to design around

  • account_beneficial_owner is unsupported in preprod. Do not treat a preprod pass on an onboarding payload as proof the field works in production.
  • atpcq is absent from the resolution config. Pick a different series for anything resolution-shaped.
  • priceScale 100 and 1000 are both live in production, and two of 121 open ATP instruments publish priceScale: 1000 with fractionalQtyScale: 100. Whichever instruments preprod happens to serve you is not a sample of production scale combinations. Read both scales per instrument. → Money on the wire
  • Tennis home_team_name, away_team_name and tournament_name are populated in preprod. The same fields have been reported empty in production.
Tennis reference fields differ by environment. Do not build a display path that depends on those fields being present.Treat them as optional in both environments until this is confirmed.

Preprod-only error strings

Neither string indicates a fault in your client. Both are worth reporting verbatim, with the environment named.

Funding a preprod pool

There is no self-service test funding. Preprod pools are funded manually by us on a Slack request. Ask in your shared channel, name the firm, and ask for an amount that covers your whole test plan rather than one run — a request per run costs you a round trip through a human each time. Test cash behaves like production cash once it is there: you move it into a participant account with Transfer, and it stays in that account. → Move cash
The transfer rate limit is being confirmed and no number should be coded against yet.One of the live statements describes a ceiling shared across all partners on preprod, which would mean another partner’s transfer traffic can throttle yours. Do not size your transfer loop against any of these until your integration lead confirms one. This blocked a partner’s entire order flow as their stated number-one issue.

Maintenance and data retention

The FAQ presents a stable Thursday 2am–4am ET window. Through August and September 2026 preprod actually ran near-weekly one-off windows at 2–8am, 3–7am, 4–7am and 5–8am. Stored execution history is archived during maintenance, and execution queries for the period before a window return empty. This is a retention fact, not a bug: if your reconciliation test reads yesterday’s executions after an overnight window, it will legitimately read nothing. Persist your own copy of every execution as it arrives on drop copy and reconcile against that. → Daily reconciliation
There is no published preprod maintenance calendar. Ask your integration lead before scheduling a certification run, and do not schedule one overnight ET.

What preprod does not give you

  • No preprod status page. status.polymarketexchange.com covers production only.
  • No working preprod health endpoint. GET /v1/health is documented as {"status":"ok"} with no auth, but partners have reported 404 in production and 401 in preprod against it.
  • No published maintenance calendar, per above.
GET /v1/health is not a usable liveness check. Do not use it as a liveness check. The combined effect of these three gaps is that when preprod is down you cannot tell it is down. Treat an unexplained preprod failure as ours until proven otherwise and post it in Slack with a timestamp. → Support and escalation

Test harness

This section tells you which parts of your integration you can drive to a known outcome on demand, and which you cannot, so you size your test plan against what exists rather than what you would expect to exist.

Start from the examples repo

github.com/Polymarket-US/partner-api-examples contains runnable scripts plus a full end-to-end test covering order placement, execution and balance update via drop copy. It is not linked from any other docs page, which is why most partners have never seen it. Clone it before you write your own harness; it is the only worked example of the full money path we publish. The repo is not a substitute for pinning your protos. The proto bundle is an unversioned, anonymous Drive zip with no changelog and no checksum, so neither side can tell which build you hold. → Protos and SDKs

What you can deterministically test

The KYC magic-value pattern exists and works, but the published DOB fixture table does not.Magic DOBs are real, and the table of them has drifted and returned wrong outcomes at least twice. Ask your integration lead for a current fixture set instead of coding against a published DOB.

The fixtures that do not exist

Say this plainly, because four partners have each built a plan around one of them: the KYC magic-value pattern has no equivalent for orders, transfers, market state or settlement. There is no way to ask the platform for a fill, a rejection, a state transition or a resolution. Four partners have asked for an on-demand “resolve this market” facility by name. It does not exist. One asked six times over 40 days and never got a settlement test.
Deterministic fixtures for orders, transfers, market state and resolution are not yet published.Do not plan a certification date against any of these four. Ask your integration lead for status before you commit one to a client.

Workarounds that actually work

Self-seed depth from a second preprod session

Because you are always the taker, the only way to get a fill is for depth to exist at your price. You can create that depth yourself: run a second preprod session that rests an order through the legacy OrderEntryAPI/insertOrder, then take it with CreateVendorOrder from your integration session.
This workaround and UAT §0 contradict each other. UAT §0 asks you to disavow legacy order entry, and this is legacy order entry. A partner cannot resolve that alone. Get it in writing from your integration lead before you rely on it, and see Certification, where the same issue is flagged.
OrderEntryAPI is exactly CreateOrderSubscription, InsertOrder and CancelOrder. Day orders cancel at the traded-day roll as of 2026-09-13 (v0.0.89), so a seeded resting order does not survive the roll; use GTD or re-seed each day.

Ask for a resolution on a market you already hold

Take a position first, then ask in Slack for that specific symbol to be resolved. Asking for “a market that resolves” produces nothing, because none do. Do not pick an atpcq symbol — atpcq is absent from the preprod resolution config.

Ask for test funds in one request

Preprod pools are funded manually by us on a Slack request. Ask once, for the whole test plan.

Test data rules that will bite you

One SSN maps to exactly one exchange account, platform-wide, because the trading account ID is derived from it. Reusing a test SSN across test users points all of them at a single account, which breaks transfers with NOT_FOUND and requires manual database cleanup by us. That failure produced a 66-reply incident thread. Generate a distinct SSN per test user and keep a registry of which ones you have burned, because there is no re-KYC, reset or PII-update path — a user whose SSN is already in use cannot be re-KYC’d by you. Other constraints your generator must respect:
  • external_id is max 49 characters.
  • postal_code must be five digits.
  • Requests are snake_case, REST responses are camelCase, webhooks are snake_case. A test that asserts one casing across all three will fail on two of them.
  • Set docv_eligible: true unless you are deliberately testing the slow path. Without it, REVIEW cases go to manual review, 1–2 business days, which will stall a test run for two days.
  • Treat the Digital Intelligence session_token as required even though it is optional on paper. It is what keeps the REVIEW rate down.
Wait for the kyc.approved webhook before you enable trading for a test user. On an ACCEPT, participantId can come back empty while provisioning finishes, with observed gaps from ~500 ms up to 26 minutes. A harness that reads participantId straight off the ACCEPT response will pass locally and fail in CI. → Firms, participants and accounts

Assertions worth building into the harness

  • Every order response asserts on status being one of exactly ACCEPTED, REJECTED, PENDING. An exchange-level rejection arrives as gRPC OK with status = REJECTED, so a test that only checks the gRPC status code will pass on a rejected order.
  • Every de-scaling assertion reads priceScale and fractionalQtyScale off the instrument in the same test, and asserts the divisor is their product. A hard-coded 10,000 passes on most instruments and is wrong by 10× on the rest.
  • Every fee assertion computes Fee = Θ × C × p × (1 − p) with C as the de-scaled contract count. Using raw order_qty on a fractional_quantity_scale = 100 instrument overstates the fee 100×, and instruments with scale 1 make the naive math accidentally correct, so this bug hides until your first scale-100 fill.
  • Every stream test counts open streams against the 20 concurrent streams per firm cap, across all gRPC subscriptions, and asserts you are under it before opening another.

What can go wrong

Next

Certification