6.0 KiB
Authentication
Polymarket uses two-level auth: L1 (EIP-712 private key signing) to create credentials, L2 (HMAC-SHA256 API key signing) to authenticate requests. Builder program adds a separate set of builder headers for order attribution and relayer access.
L1 Authentication (Private Key)
L1 proves wallet ownership via EIP-712 signature. Used to create or derive API credentials.
EIP-712 Domain
const domain = {
name: "ClobAuthDomain",
version: "1",
chainId: 137,
};
const types = {
ClobAuth: [
{ name: "address", type: "address" },
{ name: "timestamp", type: "string" },
{ name: "nonce", type: "uint256" },
{ name: "message", type: "string" },
],
};
const value = {
address: signingAddress, // The signing address
timestamp: ts, // The CLOB API server timestamp
nonce: nonce, // The nonce used
message: "This message attests that I control the given wallet",
};
L1 Headers
| Header | Description |
|---|---|
POLY_ADDRESS |
Polygon signer address |
POLY_SIGNATURE |
CLOB EIP-712 signature |
POLY_TIMESTAMP |
Current UNIX timestamp |
POLY_NONCE |
Nonce (default: 0) |
Create / Derive Credentials
// TypeScript
const client = new ClobClient("https://clob.polymarket.com", 137, signer);
const creds = await client.createOrDeriveApiKey();
// { apiKey: "uuid", secret: "base64...", passphrase: "string" }
# Python
client = ClobClient("https://clob.polymarket.com", key=pk, chain_id=137)
creds = client.create_or_derive_api_creds()
REST endpoints:
POST {host}/auth/api-key— create new credentials (requires L1 headers)GET {host}/auth/derive-api-key— derive existing credentials (requires L1 headers)
L2 Authentication (API Key)
L2 uses HMAC-SHA256 signatures from the API credentials. Required for all /v1/trade/* endpoints.
L2 Headers (all 5 required)
| Header | Description |
|---|---|
POLY_ADDRESS |
Polygon signer address |
POLY_SIGNATURE |
HMAC signature for request |
POLY_TIMESTAMP |
Current UNIX timestamp |
POLY_API_KEY |
User's API apiKey value |
POLY_PASSPHRASE |
User's API passphrase value |
Initialize Trading Client
// TypeScript
const client = new ClobClient(
"https://clob.polymarket.com",
137,
signer,
apiCreds, // { apiKey, secret, passphrase }
2, // signatureType
funderAddress // proxy wallet address
);
# Python
client = ClobClient(
host="https://clob.polymarket.com",
chain_id=137,
key=pk,
creds=api_creds,
signature_type=2,
funder=funder_address,
)
Signature Types
| Type | Value | When to Use |
|---|---|---|
| EOA | 0 |
Standard Ethereum wallet (MetaMask). Funder is the EOA address and will need POL to pay gas on transactions. |
| POLY_PROXY | 1 |
A custom proxy wallet only used with users who logged in via Magic Link email/Google. Using this requires the user to have exported their PK from Polymarket.com and imported into your app. |
| GNOSIS_SAFE | 2 |
Gnosis Safe multisig proxy wallet (most common). Use this for any new or returning user who does not fit the other 2 types. |
The funder is the address holding funds. For proxy wallets, find it at polymarket.com/settings. Proxy wallets are auto-deployed on first Polymarket.com login.
Builder Headers
Builder authentication is separate from L1/L2. Used for order attribution and relayer access.
Builder Headers (4 required)
| Header | Description |
|---|---|
POLY_BUILDER_API_KEY |
Builder API key |
POLY_BUILDER_TIMESTAMP |
Unix timestamp |
POLY_BUILDER_PASSPHRASE |
Builder passphrase |
POLY_BUILDER_SIGNATURE |
HMAC-SHA256 of request |
Initialize Client with Builder Config
// TypeScript — local signing
import { BuilderConfig, BuilderApiKeyCreds } from "@polymarket/builder-signing-sdk";
const builderCreds: BuilderApiKeyCreds = {
key: process.env.POLY_BUILDER_API_KEY!,
secret: process.env.POLY_BUILDER_SECRET!,
passphrase: process.env.POLY_BUILDER_PASSPHRASE!,
};
const builderConfig = new BuilderConfig({ localBuilderCreds: builderCreds });
const client = new ClobClient(
"https://clob.polymarket.com",
137,
signer,
apiCreds,
2,
funderAddress,
undefined,
false,
builderConfig
);
// Orders automatically include builder headers
# Python — local signing
from py_builder_signing_sdk import BuilderConfig, BuilderApiKeyCreds
builder_config = BuilderConfig(
local_builder_creds=BuilderApiKeyCreds(
key=os.environ["POLY_BUILDER_API_KEY"],
secret=os.environ["POLY_BUILDER_SECRET"],
passphrase=os.environ["POLY_BUILDER_PASSPHRASE"],
)
)
client = ClobClient(
host="https://clob.polymarket.com",
chain_id=137,
key=pk,
creds=api_creds,
signature_type=2,
funder=funder_address,
builder_config=builder_config,
)
Remote Signing
Keep builder credentials on a separate server. Client points to your signing endpoint:
// TypeScript client
const builderConfig = new BuilderConfig({
remoteBuilderConfig: { url: "https://your-server.com/sign" },
});
# Python client
from py_builder_signing_sdk import BuilderConfig, RemoteBuilderConfig
builder_config = BuilderConfig(
remote_builder_config=RemoteBuilderConfig(url="https://your-server.com/sign")
)
Your server receives { method, path, body } and returns the 4 POLY_BUILDER_* headers.
Credential Lifecycle
- Create:
client.createApiKey()— generates new credentials with a nonce - Derive:
client.deriveApiKey(nonce)— recovers existing credentials if you know the nonce - Create or Derive:
client.createOrDeriveApiKey()— creates if first time, derives if existing - Revoke builder key:
client.revokeBuilderApiKey()— invalidate compromised builder credentials
Lost credentials + lost nonce = create fresh credentials. Save your nonce.