Skip to main content
The Polymarket Exchange API uses Private Key JWT authentication with RSA keys. You sign a JWT with your RSA private key and exchange it for an access token.
Complete Onboarding first to generate your keys and receive your Client ID.

Environments

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:
  1. Create a signed JWT assertion - Sign a JWT with your private key
  2. Exchange for API access token - Send the assertion to the token endpoint
  3. Call API with access token - Include the token in your API requests

Prerequisites

After completing Onboarding, you will have:

Create Client Assertion JWT

Create a JWT with these claims, signed with your private key using RS256:

Request Access Token

Token Response

Complete Python Example

Required packages:

Complete Go Example

Using the Access Token

Include the access token in the Authorization 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:
  1. Generate a new key pair
  2. Complete a new Onboarding submission with the new public key
  3. We add the new key to your application
  4. Update your systems to use the new private key
  5. Notify us to remove the old public key

Troubleshooting

Common Errors

Debugging JWT Claims

If authentication fails, verify your client assertion JWT contains correct claims:
Common mistakes:
  • 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

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

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.
/v1/incentives/earnings is currently disabled in preprod and returns a route-not-found error there. The endpoint is live in dev01 and prod. Earnings flow shape can still be validated against the OpenAPI schema and the incentives overview.

Permission Denied Response

When a request’s token is missing the required scope:
If you receive this error, update your Auth0 application to include the missing scope and request a fresh access token.

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.

Additional Resources

For more details on Private Key JWT authentication: