Polymarket Bot Authentication: API Keys, EIP-712, and Proxy Wallets (2026)
Polymarket authentication separates three concerns: identity (your Polygon wallet signs an EIP-712 message), sessions (that signature derives API key, secret, and passphrase for L2 HMAC auth on every REST call), and funds (a proxy wallet holds collateral while a separate key signs trades). Get this structure right and a compromised bot never means a compromised treasury.
What are L1 and L2 auth?
| Layer | What signs | Where used |
|---|---|---|
| L1 | Your private key, EIP-712 structured message | Order creation; one-time credential derivation |
| L2 | HMAC with derived apiKey + secret + passphrase | Every authenticated REST/WebSocket call |
The derivation is one-time: sign the auth request with your wallet, receive the credential triple, and use those headers everywhere. The private key never needs to appear in day-to-day API traffic.
What is the proxy wallet and why does it matter?
Polymarket routes trading through a proxy: your main wallet (EOA) signs a one-time create-proxy request, and the returned proxy address holds your funds and signs trade requests with its own key.
| Key | Holds funds | Signs orders | Leak impact |
|---|---|---|---|
| Main EOA | No (it creates the proxy) | No | Account control — cold storage |
| Proxy key | The collateral | Yes (orders, API auth) | Trading key — rotate/revoke |
This is the bot-operator pattern: the proxy key lives on the VPS, the main key lives offline. A leaked proxy key risks the collateral in that account — not your identity, not your other wallets.
What does the signing code look like?
# L1: derive credentials (once, store the triple securely)
creds = client.create_or_derive_api_creds()
# L2: every authenticated call carries the triple
client = ClobClient(
host="https://clob.polymarket.com",
key=PROXY_PRIVATE_KEY, # the proxy's key, not the main EOA
chain_id=137,
signature_type=1, # 1 = Polymarket proxy
funder=PROXY_ADDRESS, # where collateral lives
creds=creds,
)
# Order placement signs an EIP-712 message under the hood:
order = client.create_order(MarketOrderArgs(
token_id=TOKEN, amount="25", side="BUY",
))
What are the operational rules?
- Never reuse a stale timestamp — signed requests need fresh
ts(ms) andsalt; reuse or skew gets rejected. Sync againstGET /v1/info/time - Rotate proxy keys on any suspicion; the main EOA never rotates
- Scope credentials per environment — dev bot and prod bot get different proxies; never share a signing identity across machines
- On perps, note the EOA convention — your perps account is keyed by the EOA base address even if you use a Safe wallet elsewhere
- Env-vars over config files for the key material; no keys in git, ever
How does this compare to CEX API keys?
The shape is familiar (key + secret + passphrase, like a CEX), but the trust model is different: credentials derive from your own wallet signature, not from a company’s database — and order validity is enforced by signature, not by session cookies. That’s why clock skew matters more here, and why the proxy separation is worth setting up before the first bot run.
FAQ
Q: Do I need my private key on the bot server? A: One key must sign orders — but it should be the proxy wallet’s key, not your main EOA. The main key stays offline; the proxy key is the expendable one.
Q: What is EIP-712 on Polymarket? A: The structured-message signing standard. Orders are EIP-712 messages the CLOB can verify; “market orders” are limit orders priced to execute immediately, signed the same way.
Q: Where do the apiKey/secret/passphrase come from? A: You derive them: sign the credential request with your wallet, receive the triple, and attach it as headers (L2 auth) on subsequent calls.
Q: Why do my signed requests get rejected randomly? A: Clock skew. Timestamps must be fresh; sync the server against the platform time endpoint and avoid signing far in the past or future.
Q: What’s the difference between the funder and the signer? A: The funder (proxy address) holds the collateral the trade settles against; the signer (proxy key) authorizes it. They’re paired one-to-one per proxy wallet.
Sources
Disclaimer
Not financial advice. Educational purposes only. Updated October 2026.