Skip to main content
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:

Builder API Credentials

Each builder receives API credentials from their Builder Profile:
CredentialDescription
keyYour builder API key identifier
secretSecret key for signing requests
passphraseAdditional authentication passphrase
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.

Remote Signing

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:
import {
  buildHmacSignature,
  BuilderApiKeyCreds,
} from "@polymarket/builder-signing-sdk";

const BUILDER_CREDENTIALS: BuilderApiKeyCreds = {
  key: process.env.POLY_BUILDER_API_KEY!,
  secret: process.env.POLY_BUILDER_SECRET!,
  passphrase: process.env.POLY_BUILDER_PASSPHRASE!,
};

// 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,
  };
}

Client Configuration

Point the CLOB client to your signing server:
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 client = new ClobClient(
  "https://clob.polymarket.com",
  137,
  signer,
  apiCreds,
  2, // signature type
  funderAddress,
  undefined,
  false,
  builderConfig,
);

// Orders automatically include builder headers
const response = await client.createAndPostOrder(/* ... */);

Local Signing

Sign orders locally when you control the entire order placement flow (e.g., your backend places orders on behalf of users):
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(/* ... */);

Authentication Headers

The SDK automatically generates and attaches these headers to each request:
HeaderDescription
POLY_BUILDER_API_KEYYour builder API key
POLY_BUILDER_TIMESTAMPUnix timestamp of signature creation
POLY_BUILDER_PASSPHRASEYour builder passphrase
POLY_BUILDER_SIGNATUREHMAC signature of the request
With local signing, the SDK constructs and attaches these headers automatically. With remote signing, your server returns these headers and the SDK attaches them.

Verifying Attribution

Get Builder Trades

Query trades attributed to your builder account to verify attribution is working:
const trades = await client.getBuilderTrades();

// Filtered by market
const marketTrades = await client.getBuilderTrades({
  market: "0xbd31dc8a...",
});
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:
await client.revokeBuilderApiKey();
After revoking, generate new credentials from your Builder Profile.

Troubleshooting

  • 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
Ensure your environment variables are set: - POLY_BUILDER_API_KEY - POLY_BUILDER_SECRET - POLY_BUILDER_PASSPHRASE
  • 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

Next Steps