L1 / L2 auth + rate limits

Polymarket API Keys — L1 / L2 Auth, Generation, Rotation, and Rate Limits

Polymarket API keys gate every CLOB request. Here is how the L1/L2 auth model actually works, how to generate and rotate keys with py-clob-client, the rate limits you will hit, and how PredictEngine handles auth automatically.

What is a Polymarket API key?

A Polymarket API key is the credential that authorizes a program to read market data, place orders, and manage positions against Polymarket's Central Limit Order Book. Without it, the CLOB returns 401 on every request that requires an authenticated identity.

Polymarket runs a two-tier auth scheme. L1 (Level 1) auth signs each request with your Ethereum private key — slow, but cryptographically tied to your address and used only for endpoints that issue or revoke API credentials. L2 (Level 2) auth uses an issued API-key triplet — API key + secret + passphrase — to compute an HMAC signature per request, which is fast and used for everything else.

In practice, you sign once with your private key to issue an L2 key, then use that L2 key for thousands of subsequent CLOB calls. The L2 key sits in environment variables on your server; the private key only comes out for rotation or key revocation.

How API key generation actually works

The recipe to generate a Polymarket L2 API key with py-clob-client:

The same flow works in TypeScript via @polymarket/clob-client. Both SDKs hide the HMAC math; if you are rolling your own client, the HMAC scheme is documented but easy to mis-implement.

  • Initialize the client with your private key and the Polygon chain ID (137).
  • Call client.create_api_key() — internally this signs a structured message with your private key.
  • The CLOB validates the signature, issues an L2 key triplet (key, secret, passphrase), and returns it.
  • Store the triplet in a secure location (environment variable, KMS-backed secret store) — the secret and passphrase cannot be re-fetched, only re-issued.
  • Configure subsequent client calls with the L2 credentials; HMAC signing happens per-request inside py-clob-client.

Why API key management is hard in production

API keys are simple in isolation and painful at scale. The operational issues that bite real systems:

  • Storage and rotation — keys cannot live in a Git repo, a public env file, or browser localStorage. You either run a secret manager (AWS KMS, Vault, Doppler) or accept the risk of leakage. Rotation cadence matters; long-lived keys are a security debt.
  • 401 recovery — when an L2 key expires or is revoked, every subsequent request 401s. You catch the 401, re-issue an L2 key via L1 auth, and resume — without losing in-flight orders.
  • Rate limit handling — Polymarket enforces per-IP and per-key rate limits. Bursting past them returns 429. Naive retry loops on 429 turn into rate-limit ban hammers; correct handling is exponential backoff with jitter.
  • Multi-bot key sharing — if you run multiple bots from the same wallet, they share a key. One bot's misbehavior (excessive cancel/replace) can rate-limit the others. Separating bots by key or by wallet avoids this.
  • Read vs write throttling — the CLOB throttles order placement more aggressively than market-data reads. A bot that polls /markets aggressively will rate-limit itself out of placing orders.
  • Time-skew rejections — HMAC signatures include a timestamp. If your server clock drifts more than a few seconds, requests reject. Run NTP.
  • Auth library mismatch — community-maintained Polymarket clients sometimes implement HMAC incorrectly. Stick to py-clob-client / @polymarket/clob-client; they are the reference implementations.

Building API key management yourself vs PredictEngine

What you own in each path:

ConcernBuilding yourselfPredictEngine
Initial key generationYou call create_api_key() via L1 authAuto-issued per user on first use
Secret storageYou run KMS / Vault / env varsEncrypted at rest, never exposed to UI
Rotation cadenceYou schedule rotationPlatform-managed rotation
401 recoveryYou catch + re-issue mid-flightHandled in service
429 rate-limit handlingYou write exponential backoffBuilt-in throttling
Per-bot key isolationYou generate per-bot keysPer-user isolation
HMAC signing per requestProvided by SDK; you wire itHandled in service
Clock-skew guardYou run NTP on every serverHandled in service

How PredictEngine handles Polymarket API auth

PredictEngine generates an L2 API-key triplet per user on first use. Credentials are encrypted at rest using AES with a platform-managed key, decrypted in memory only at signing time, and never returned to the user-facing UI. The L1 private key used for key issuance is the same wallet key encrypted in the user's wallet record — single key, dual purpose.

On 401 (key expired or revoked), the platform re-issues automatically via L1 auth and resumes. On 429, the platform throttles using exponential backoff with jitter per the documented Polymarket recommendation. Per-user keys means one user's rate-limit issues do not cascade to other users.

For the user: never see a key, never store a secret, never debug a 401. The auth layer is a platform internal.

When to manage your own API keys

Manage your own keys when you have an existing secrets-management stack (KMS, Vault) that you must integrate with, when you are running enough requests that the platform's rate-limit-aware throttling becomes a constraint, or when you need fine-grained per-bot key isolation that the platform's per-user model does not give you.

Use PredictEngine's managed-auth path for everything else. The L1/L2 dance, the 401 recovery, the 429 backoff — none of it is interesting work; it just needs to be done correctly and once.

Stop managing API keys.

PredictEngine issues, encrypts, and rotates Polymarket API credentials per user. Rate-limit-aware throttling and 401 recovery are platform internals.

Frequently Asked Questions

Related