Skip to main content
This is the path from nothing to an authenticated call: the hostnames, the keypair, the token, the grants on that token, the identity your calls address, and the stubs you generate. Each section depends on the one before it, so read it top to bottom once and come back to individual sections afterwards.
Prerequisites: a Client ID for the environment you are targeting, and the RSA keypair it is registered against. Both come out of the credential gates on Path to production. If you have neither yet, start at Generate your keys — we cannot issue a Client ID until we have a public key to register against it.
Every hostname you need is in the table below. This section is the only place in this space where these values are stated; everything else links here.

Endpoints

The gRPC hostname form is grpc-api.{env}.polymarketexchange.com, on port 443. Keys, Client IDs and scope grants are per environment. A preprod token is rejected in production and vice versa. See Generate your keys.

The APIs, by stage

Which API surface belongs to which part of the build, in build order. Reference pages live on the public documentation site and open in a new tab. This guide is authoritative for the partner surface: where the two disagree, follow this guide and tell your integration lead.
Do not use the retail API reference. api.polymarket.us with X-PM-Access-Key and an Ed25519 signature is a different product. Those credentials never work against api.*.polymarketexchange.com, and following the retail Quickstart gives you a credential model that cannot be made to work on the partner surface. Use the references above.

How many environments there are

There are three: dev, preprod and production. Partners are provisioned into preprod and production, and those are the hostnames in the table above. Dev is not part of the partner path.
Dev hostnames are not published here. If you are told to point at dev, ask for its hostnames and its credential set in writing — a preprod keypair will not work against it, the same as for production.

What differs between preprod and production

Because your order surface is fill-or-kill only, a thin preprod book blocks you completely while market makers are unaffected: they post the resting depth you need to cross.
Tennis team and tournament names differ between environments. These fields are populated in preprod and have been observed empty in production. Do not make them required in your data model on the strength of preprod.

Health checks

There is no partner-checkable health endpoint you can rely on.GET /v1/health is documented as returning {"status":"ok"} with no auth, but partners have reported 404 in production and 401 in preprod against it. Do not build liveness monitoring on it.
For production, watch status.polymarketexchange.com. For preprod there is no status signal at all — if preprod looks broken, ask in your shared Slack channel rather than assuming it is your code.

Maintenance

If you are an IB, this differs. Archived execution history is a reporting hazard for you, not just a testing annoyance: pre-maintenance execution queries return empty, and Customer Statements and reconciliation are built from that history. Persist executions as you receive them. See Reporting pack.
The legacy FAQ presents a stable Thursday 2am–4am ET window. Between August and September 2026 we actually ran near-weekly one-off windows at 2–8am, 3–7am, 4–7am and 5–8am ET.
Stored execution history is archived during maintenance, and execution queries for the pre-maintenance period return empty. This is a retention fact, not a transient error. Pull and persist anything you need to keep before a window, and do not treat an empty execution query after maintenance as data loss on your side.
No preprod maintenance calendar is published.Ask for the next window in your shared Slack channel.

Three surfaces that are not yours

Mixing these up is the single biggest source of partner confusion on our site. If you are holding an access key and an Ed25519 signing key, you have retail credentials and you are on the wrong product. Your credentials for this space are an RSA private key plus a Client ID, used to mint a Bearer token — see Authentication.
Two gateway.polymarket.us endpoints have real value for sports integrations — /v1/sports/players and /v1/sports/teams, whose long_participant_id keys to SportRadar and SDIO IDs. They were undocumented for six months and blocked one partner’s player props from March to September 2026. They are still on the retail surface; if you need them, say so rather than assuming they are supported for partners.

The institutional portal

institutional.polymarketexchange.com/register is the portal. Self-service API keys there are for market makers. Its upload forms do not apply to ISVs or IBs, and ISV provisioning is fully manual today, so do not wait on a portal step that will never complete.

Protos and SDKs

Most of this surface is gRPC, so the last step is stubs. Generate them from the proto bundle we hand you, not from server reflection. The bundle has known gaps, listed below — read them before you generate, because two of them sit directly on your money path.

Get the bundle

Ask your integration lead for polymarket-protos.zip.
The bundle is unversioned. It ships as an anonymous Google Drive zip with no changelog and no checksum, so neither side can tell which build you are holding.Until that changes, version it yourself and quote the digest in every ticket:
Commit the digest next to your generated code. When a call starts failing on a schema mismatch, the digest is the only evidence either side has of what you built against.
One check worth running the moment you unzip:
CreateFundedOrder, PreviewFundedOrder and OdfSweep were removed on 2026-08-06 and replaced by CreateVendorOrder plus Transfer. That removal shipped without a changelog entry, and a partner discovered it through reflection when their entire money path broke.

Generate stubs

If protoc fails with a missing go_package, the bundle’s files do not all carry option go_package. Map them on the command line rather than editing the bundle — editing it means your next bundle silently reverts your fix:
Two package prefixes appear on the wire — polymarket.v1 (for example /polymarket.v1.PositionAPI/ListAccountBalances) and connamara.ep3.v1beta1. Generate from the whole bundle rather than cherry-picking files, so you get both.

What the bundle does not contain

The bundle advertises 14 services and defines 5. Nine are named and never documented: OrderAPI, PositionAPI, AccountsAPI, MarketDataAPI, DropCopyAPI, KYCAPI, AeropayAPI, CheckoutAPI, HealthAPI. Do not plan work against a service you can only see named.
OrderFundingService and CashMovementService are absent from the bundle — which is exactly where your money path lives.Ask your integration lead for those two definitions in writing before you build transfers. Do not reconstruct them from reflection or by probing field numbers; see the field-number defect below.
CreatePositionSubscription has no proto definition anywhere, in the bundle or elsewhere.
One positive: the proto reference correctly declares OrderEntryAPI as exactly CreateOrderSubscription, InsertOrder and CancelOrder — consistent with the funded-order RPCs having been removed. If your bundle disagrees, your bundle is stale.

Reflection is not authoritative

gRPC server reflection is entitlement-gated and returns PermissionDenied: method not permitted without the grant — see Scopes and entitlements. Even with the grant, do not treat it as the schema of record. The bundle we hand you is authoritative over reflection. Two incidents make the point:
  • Reflection advertised a stale schema. order.clord_id is required by the runtime on CreateVendorOrder, and reflection advertised the older schema without it for a period. PreviewOrder ignores clord_id; Create requires it.
  • A published proto carried a wrong field number. In CreateCashMovement, transfer is field 4 in the real service. The published version omitted an internal intent occupying field 2 and renumbered transfer down to fill the gap. A partner’s "20.00" therefore arrived as that internal intent — which is why the error they got named amount.
Never infer a field number by probing a live service. A partner got funded orders working by inferring clord_id was field 12 and testing against a live order. It worked, and it was a real order on a real money path. If a field you need is absent from the bundle, ask for the definition.
If reflection and the bundle disagree, report the disagreement with your bundle digest. Do not pick the one that makes your code compile.

Two wire behaviours that bite

  • int64 fields are serialized as strings in JSON. Parse them as strings and convert deliberately; a JSON number will lose precision.
  • proto3 does not put scalar fields at their default value on the wire, so an absent field and a zero are indistinguishable. This matters wherever zero is meaningful — GetTradeStats returns empty buckets as all-zero objects, and zero there means “no trades”, never a print at price 0.

Examples repo

github.com/Polymarket-US/partner-api-examples holds scripts plus a full end-to-end test covering order placement, execution and balance update via drop copy. It is not linked from any legacy docs page. Use the e2e test as your integration target: if it passes against your credentials, your token minting, metadata, scales and drop-copy consumption are all wired correctly.
The examples repo is not versioned against the proto bundle.If the examples fail to compile against your generated stubs, check the bundle digest before debugging your code.

What can go wrong

Next

Authentication