Complete Onboarding first to generate your keys and receive your Client ID.
Environments
| Environment | Auth Domain | API Domain |
|---|---|---|
| Development | pmx-dev01.us.auth0.com | api.dev01.polymarketexchange.com |
| Pre-production | pmx-preprod.us.auth0.com | api.preprod.polymarketexchange.com |
| Production | pmx-prod.us.auth0.com | api.prod.polymarketexchange.com |
Use
https://[API Domain] for both the JWT audience claim and API base URL.Each environment requires separate onboarding. Your pre-production credentials will not work in production.
How It Works
Authentication follows these steps:- Create a signed JWT assertion - Sign a JWT with your private key
- Exchange for API access token - Send the assertion to the token endpoint
- Call API with access token - Include the token in your API requests
Prerequisites
After completing Onboarding, you will have:| You Have | From Onboarding |
|---|---|
| Private key file | Generated by you (keep secure!) |
| Client ID | Provided by Polymarket via clientid.txt in your shared Google Drive folder |
| Auth Domain | See Environments |
| API Audience | See Environments |
Create Client Assertion JWT
Create a JWT with these claims, signed with your private key using RS256:| Claim | Description |
|---|---|
iss | Your client ID (issuer) |
sub | Your client ID (subject) |
aud | Token endpoint URL |
iat | Issued at time (Unix timestamp) |
exp | Expiration time (max 5 minutes from iat) |
jti | Unique token ID (prevents replay attacks) |
Request Access Token
Token Response
Complete Python Example
Complete Go Example
Using the Access Token
Include the access token in theAuthorization header for all API requests. For account-scoped endpoints (trading, positions, reports), you must also include the x-participant-id header.
REST API
gRPC
Verify your token scopes and ensure
x-participant-id is included for account-scoped endpoints. If you don’t know your participant ID, call GET /v1/whoami or GET /v1/users and put your firm and user into the firms/<YOURFIRM>/users/<USER> format. Note you will have one firm but can have multiple users.Key Rotation
You can rotate your keys at any time:- Generate a new key pair
- Complete a new Onboarding submission with the new public key
- We add the new key to your application
- Update your systems to use the new private key
- Notify us to remove the old public key
Troubleshooting
Common Errors
| Error | Cause | Solution |
|---|---|---|
invalid_client | JWT signature verification failed | Verify private key matches registered public key |
invalid_client_assertion | Malformed JWT or wrong claims | Check JWT claims (iss, sub, aud, exp) |
401 Unauthorized | Invalid or expired access token | Request a new access token |
Debugging JWT Claims
If authentication fails, verify your client assertion JWT contains correct claims:- Wrong
aud(must be the token endpoint, not the API) - Expired JWT (exp in the past)
- Reused
jti(must be unique per request)
API Scopes
Your application is granted specific scopes that control which API endpoints you can access. Scopes are included in your access token and validated by the API.Available Scopes
| Scope | Description |
|---|---|
read:marketdata | BBO (best bid/offer) and market data subscriptions (including BiDirectionalStreamMarketData) |
read:l2marketdata | L2 orderbook depth (premium) |
read:instruments | RefData, instrument listings and metadata |
read:orders | View open orders, preview orders, order subscriptions, combo RFQs, quotes, and RFQ event streams |
write:orders | Insert / cancel / replace / modify orders; create, quote, delete, and accept combo RFQs |
read:reports | Search/download orders, trades, executions, and incentives earnings |
read:positions | Position queries, balance queries, position ledger, balance ledger, and position valuations (including historical via as_of_time / as_of_date) |
read:dropcopy | Drop copy subscriptions |
read:accounts | View users (/v1/whoami, /v1/users) and account info |
read:funding | View funding sources and transactions |
write:funding | Update funding, create deposits and withdrawals |
Strict scope enforcement. Calls that are missing a required scope fail with
403 Forbidden (REST) / PERMISSION_DENIED (gRPC) and the message permission denied: missing required scope <scope>. Balance ledger endpoints use read:positions (not read:funding) to stay consistent with the existing balance-query endpoints (GetAccountBalance, ListAccountBalances).Scope Requirements by Endpoint
| Endpoint | Method | Required Scope |
|---|---|---|
/v1/trading/orders | POST | write:orders |
/v1/trading/orders/cancel | POST | write:orders |
/v1/trading/orders/open | GET | read:orders |
/v1/combos/rfq/user-id | GET | read:orders |
/v1/combos/rfqs | GET | read:orders |
/v1/combos/rfqs | POST | write:orders |
/v1/combos/quotes | GET | read:orders |
/v1/combos/quotes | POST | write:orders |
/v1/combos/rfqs/{rfqId}/quotes/{quoteId} | DELETE | write:orders |
/v1/combos/rfqs/{rfqId}/quotes/{quoteId}/accept | PUT | write:orders |
StreamRFQEvents (gRPC) | — | read:orders |
/v1/report/orders/search | POST | read:reports |
/v1/report/trades/search | POST | read:reports |
/v1/incentives/earnings | GET | read:reports (disabled in preprod) |
/v1/positions | GET | read:positions |
/v1/positions/balance | POST | read:positions |
/v1/positions/balances | POST | read:positions |
/v1/positions/ledger | GET | read:positions |
/v1/positions/ledger/download | GET | read:positions |
/v1/funding/balance-ledger | GET | read:positions |
/v1/funding/balance-ledger/download | GET | read:positions |
CreateBalanceLedgerSubscription (gRPC) | — | read:positions |
/v1/valuations/positions | GET | read:positions |
/v1/valuations/positions/download | GET | read:positions |
/v1/valuations/accounts/statement/download | POST | read:positions |
/v1/orderbook/{symbol} | GET | read:l2marketdata |
/v1/orderbook/{symbol}/bbo | GET | read:marketdata |
BiDirectionalStreamMarketData (gRPC) | — | read:marketdata |
CreateMarketDataSubscription (gRPC) | — | read:marketdata |
/v1/refdata/symbols | POST | read:instruments |
/v1/refdata/instruments | POST | read:instruments |
/v1/refdata/metadata | POST | read:instruments |
/v1/whoami | GET | read:accounts |
/v1/users | GET | read:accounts |
/v1/funding/accounts | GET | read:funding |
/v1/aeropay/deposits | POST | write:funding |
/v1/checkout/deposits | POST | write:funding |
/v1/health | GET | (no auth required) |
gRPC streams (
BiDirectionalStreamMarketData, CreateMarketDataSubscription, CreateBalanceLedgerSubscription, StreamRFQEvents) run on a separate ALB (grpc-api.{env}.polymarketexchange.com:443) that bypasses the API Gateway and its 30-second idle timeout. Scope validation for these streams happens at the application layer rather than at the load balancer, but the resulting PERMISSION_DENIED behavior is identical to REST endpoints.Permission Denied Response
When a request’s token is missing the required scope:| Surface | Status / Code |
|---|---|
| REST | 403 Forbidden |
| gRPC | PERMISSION_DENIED (code 7) |
Checking Your Scopes
Your granted scopes are included in your access token. You can decode the token to see them:If you receive a
403 Forbidden error, check that your application has been granted the required scope for that endpoint. Contact support to request additional scopes.