docs: sync with official Polymarket docs - 2026-04-20

This commit is contained in:
Etherdrake
2026-04-20 01:19:37 +02:00
parent 3ad0048c35
commit ff4882db02
50 changed files with 705 additions and 1857 deletions
+54 -301
View File
@@ -4,301 +4,93 @@
# Order Attribution
> Attribute orders to your builder key for volume credit
> Attribute orders to your builder code for volume credit and fee rewards
Order attribution adds builder authentication headers when placing orders through the CLOB, enabling Polymarket to credit trades to your builder account. This allows you to:
Order attribution credits trades to your builder account by attaching your **builder code** to every order. This enables:
* Track volume on the [Builder Leaderboard](https://builders.polymarket.com/)
* Earn rewards through the [Builder Program](/builders/overview)
* Monitor performance via the Data API
* Volume tracking on the [Builder Leaderboard](https://builders.polymarket.com/)
* Fee rewards through the [Builder Program](/builders/overview)
* Performance monitoring via the Data API
***
## Builder API Credentials
## Builder Code
Each builder receives API credentials from their [Builder Profile](https://polymarket.com/settings?tab=builder):
Your **builder code** is a `bytes32` identifier tied to your builder profile. Find it at [polymarket.com/settings?tab=builder](https://polymarket.com/settings?tab=builder).
| Credential | Description |
| ------------ | ------------------------------------ |
| `key` | Your builder API key identifier |
| `secret` | Secret key for signing requests |
| `passphrase` | Additional authentication passphrase |
That's the only credential you need for attribution — no HMAC signing, no separate API key, no special headers.
<Warning>
Builder API credentials are **not** the same as user API credentials. Builder
credentials are for order attribution only — you still need user credentials
for authentication. Never expose builder credentials in client-side code or
commit them to version control.
</Warning>
<Note>
Builder codes are public identifiers — they appear onchain in the `builder` field of every order you attribute. Only you control which orders include your code, so keep it scoped to apps you own.
</Note>
***
## Remote Signing
## Attaching the Builder Code
Remote signing keeps your builder credentials secure on a server you control. The user's client sends order details to your server, which adds the builder headers before forwarding to the CLOB.
### Server Implementation
Your signing server receives request details and returns the authentication headers:
Pass `builderCode` in the order struct on every order you submit. The SDK serializes it into the onchain order's `builder` field, and the protocol attributes every matched trade to your profile.
<CodeGroup>
```typescript TypeScript theme={null}
import {
buildHmacSignature,
BuilderApiKeyCreds,
} from "@polymarket/builder-signing-sdk";
import { ClobClient, Side, OrderType } from "@polymarket/clob-client-v2";
const BUILDER_CREDENTIALS: BuilderApiKeyCreds = {
key: process.env.POLY_BUILDER_API_KEY!,
secret: process.env.POLY_BUILDER_SECRET!,
passphrase: process.env.POLY_BUILDER_PASSPHRASE!,
};
const client = new ClobClient({
host: "https://clob.polymarket.com",
chain: 137,
signer,
creds: apiCreds,
signatureType: 2,
funderAddress,
});
// POST /sign - receives { method, path, body } from the client SDK
export async function handleSignRequest(request) {
const { method, path, body } = await request.json();
const timestamp = Date.now().toString();
const signature = buildHmacSignature(
BUILDER_CREDENTIALS.secret,
parseInt(timestamp),
method,
path,
body,
);
return {
POLY_BUILDER_SIGNATURE: signature,
POLY_BUILDER_TIMESTAMP: timestamp,
POLY_BUILDER_API_KEY: BUILDER_CREDENTIALS.key,
POLY_BUILDER_PASSPHRASE: BUILDER_CREDENTIALS.passphrase,
};
}
```
```python Python theme={null}
import os
import time
from py_builder_signing_sdk.signing.hmac import build_hmac_signature
from py_builder_signing_sdk import BuilderApiKeyCreds
BUILDER_CREDENTIALS = BuilderApiKeyCreds(
key=os.environ["POLY_BUILDER_API_KEY"],
secret=os.environ["POLY_BUILDER_SECRET"],
passphrase=os.environ["POLY_BUILDER_PASSPHRASE"],
)
# POST /sign - receives { method, path, body } from the client SDK
def handle_sign_request(method: str, path: str, body: str):
timestamp = str(int(time.time()))
signature = build_hmac_signature(
BUILDER_CREDENTIALS.secret,
timestamp,
method,
path,
body
)
return {
"POLY_BUILDER_SIGNATURE": signature,
"POLY_BUILDER_TIMESTAMP": timestamp,
"POLY_BUILDER_API_KEY": BUILDER_CREDENTIALS.key,
"POLY_BUILDER_PASSPHRASE": BUILDER_CREDENTIALS.passphrase,
}
```
</CodeGroup>
### Client Configuration
Point the CLOB client to your signing server:
<CodeGroup>
```typescript TypeScript theme={null}
import { ClobClient } from "@polymarket/clob-client";
import { BuilderConfig } from "@polymarket/builder-signing-sdk";
const builderConfig = new BuilderConfig({
remoteBuilderConfig: {
url: "https://your-server.com/sign",
token: "optional-auth-token", // optional
const response = await client.createAndPostOrder(
{
tokenID: "0x...",
price: 0.55,
size: 100,
side: Side.BUY,
builderCode: "0xabc123...", // your builder code from polymarket.com/settings?tab=builder
},
});
const client = new ClobClient(
"https://clob.polymarket.com",
137,
signer,
apiCreds,
2, // signature type
funderAddress,
undefined,
false,
builderConfig,
{ tickSize: "0.01", negRisk: false },
OrderType.GTC,
);
// Orders automatically include builder headers
const response = await client.createAndPostOrder(/* ... */);
```
```python Python theme={null}
from py_clob_client.client import ClobClient
from py_builder_signing_sdk import BuilderConfig, RemoteBuilderConfig
builder_config = BuilderConfig(
remote_builder_config=RemoteBuilderConfig(
url="https://your-server.com/sign",
token="optional-auth-token", # optional
)
)
from py_clob_client.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY
client = ClobClient(
host="https://clob.polymarket.com",
chain_id=137,
chain=137,
key=private_key,
creds=api_creds,
signature_type=2,
funder=funder_address,
builder_config=builder_config
)
# Orders automatically include builder headers
response = client.create_and_post_order(...)
```
```rust Rust theme={null}
use polymarket_client_sdk::auth::builder::Config as BuilderConfig;
use polymarket_client_sdk::clob::types::SignatureType;
// First, authenticate as a normal user
let client = Client::new("https://clob.polymarket.com", Config::default())?
.authentication_builder(&signer)
.signature_type(SignatureType::GnosisSafe)
.authenticate()
.await?;
// Then promote to builder with remote signing
let builder_config = BuilderConfig::remote(
"https://your-server.com/sign",
Some("optional-auth-token".to_owned()),
)?;
let client = client.promote_to_builder(builder_config).await?;
// Orders automatically include builder headers
response = client.create_and_post_order(
OrderArgs(
token_id="0x...",
price=0.55,
size=100,
side=BUY,
builder_code="0xabc123...", # your builder code from polymarket.com/settings?tab=builder
),
options={"tick_size": "0.01", "neg_risk": False},
order_type=OrderType.GTC,
)
```
</CodeGroup>
***
## Local Signing
Sign orders locally when you control the entire order placement flow (e.g., your backend places orders on behalf of users):
<CodeGroup>
```typescript TypeScript theme={null}
import { ClobClient } from "@polymarket/clob-client";
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
const response = await client.createAndPostOrder(/* ... */);
```
```python Python theme={null}
import os
from py_clob_client.client import ClobClient
from py_builder_signing_sdk import BuilderConfig, BuilderApiKeyCreds
builder_creds = BuilderApiKeyCreds(
key=os.environ["POLY_BUILDER_API_KEY"],
secret=os.environ["POLY_BUILDER_SECRET"],
passphrase=os.environ["POLY_BUILDER_PASSPHRASE"],
)
builder_config = BuilderConfig(
local_builder_creds=builder_creds,
)
client = ClobClient(
host="https://clob.polymarket.com",
chain_id=137,
key=private_key,
creds=api_creds,
signature_type=2,
funder=funder_address,
builder_config=builder_config
)
# Orders automatically include builder headers
response = client.create_and_post_order(...)
```
```rust Rust theme={null}
use polymarket_client_sdk::auth::{Credentials, builder::Config as BuilderConfig};
let builder_creds = Credentials::new(
std::env::var("POLY_BUILDER_API_KEY")?.parse()?,
std::env::var("POLY_BUILDER_SECRET")?,
std::env::var("POLY_BUILDER_PASSPHRASE")?,
);
let builder_config = BuilderConfig::local(builder_creds);
let client = client.promote_to_builder(builder_config).await?;
// Orders automatically include builder headers
```
</CodeGroup>
***
## Authentication Headers
The SDK automatically generates and attaches these headers to each request:
| Header | Description |
| ------------------------- | ------------------------------------ |
| `POLY_BUILDER_API_KEY` | Your builder API key |
| `POLY_BUILDER_TIMESTAMP` | Unix timestamp of signature creation |
| `POLY_BUILDER_PASSPHRASE` | Your builder passphrase |
| `POLY_BUILDER_SIGNATURE` | HMAC signature of the request |
<Info>
With **local signing**, the SDK constructs and attaches these headers
automatically. With **remote signing**, your server returns these headers and
the SDK attaches them.
</Info>
Every order placed with `builderCode` attached is credited to your builder profile — no additional configuration needed.
***
## Verifying Attribution
### Get Builder Trades
Query trades attributed to your builder account to verify attribution is working:
Query trades attributed to your builder code:
<CodeGroup>
```typescript TypeScript theme={null}
@@ -317,62 +109,23 @@ Query trades attributed to your builder account to verify attribution is working
market="0xbd31dc8a..."
)
```
```rust Rust theme={null}
use polymarket_client_sdk::clob::types::request::TradesRequest;
let trades = client.builder_trades(&TradesRequest::default(), None).await?;
// Filtered by market
let request = TradesRequest::builder()
.market("0xbd31dc8a...".parse()?)
.build();
let market_trades = client.builder_trades(&request, None).await?;
```
</CodeGroup>
Each `BuilderTrade` includes: `id`, `market`, `assetId`, `side`, `size`, `price`, `status`, `outcome`, `owner`, `maker`, `transactionHash`, `matchTime`, `fee`, and `feeUsdc`.
### Revoke Builder API Key
If your credentials are compromised, revoke them immediately:
<CodeGroup>
```typescript TypeScript theme={null}
await client.revokeBuilderApiKey();
```
```python Python theme={null}
client.revoke_builder_api_key()
```
```rust Rust theme={null}
client.revoke_builder_api_key().await?;
```
</CodeGroup>
After revoking, generate new credentials from your [Builder Profile](https://polymarket.com/settings?tab=builder).
Each `BuilderTrade` includes: `id`, `market`, `assetId`, `side`, `size`, `price`, `status`, `outcome`, `owner`, `maker`, `builder`, `transactionHash`, `matchTime`, `fee`, and `feeUsdc`.
***
## Troubleshooting
<AccordionGroup>
<Accordion title="Invalid Signature Errors">
* Verify the request body is passed correctly as JSON - Check that `path`,
`body`, and `method` match what the client sends - Ensure your server and
client use the same Builder API credentials
<Accordion title="Volume not appearing on the leaderboard">
* Confirm your `builderCode` is correctly attached to every order
* Check that orders are being matched (not just placed)
* Allow up to 24 hours for volume to appear on the leaderboard
</Accordion>
<Accordion title="Missing Credentials">
Ensure your environment variables are set: - `POLY_BUILDER_API_KEY` -
`POLY_BUILDER_SECRET` - `POLY_BUILDER_PASSPHRASE`
</Accordion>
<Accordion title="Volume not appearing on leaderboard">
* Confirm your builder credentials are valid and not revoked - Check that
orders are being placed with the builder config attached - Allow up to 24
hours for volume to appear on the leaderboard
<Accordion title="Invalid builder code">
Verify the code matches what's shown on [your Builder Profile](https://polymarket.com/settings?tab=builder). Builder codes are `bytes32` hex values starting with `0x`.
</Accordion>
</AccordionGroup>