Files
PolymarketDocumentation/docs/developers/builders/order-attribution.md
T
2026-02-14 12:59:26 +01:00

11 KiB

Documentation Index

Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt Use this file to discover all available pages before exploring further.

Order Attribution

Learn how to attribute orders to your builder account

Overview

The CLOB (Central Limit Order Book) is Polymarket's order matching system. Order attribution adds builder authentication headers when placing orders through the CLOB Client, 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:

Credential Description
key Your builder API key identifier
secret Secret key for signing requests
passphrase Additional authentication passphrase
**Security Notice**: Your Builder API keys must be kept secure. Never expose them in client-side code.

Signing Methods

Remote signing keeps your credentials secure on a server you control.
**How it works:**

1. User signs an order payload
2. Payload is sent to your builder signing server
3. Your server adds builder authentication headers
4. Complete order is sent to the CLOB

### Server Implementation

Your signing server receives request details and returns the authentication headers. Use the `buildHmacSignature` function from the SDK:

<CodeGroup>
  ```typescript TypeScript theme={null}
  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,
    };
  }
  ```

  ```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>

<Warning>
  Never commit credentials to version control. Use environment variables or a secrets manager.
</Warning>

### Client Configuration

Point your client to your signing server:

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { ClobClient } from "@polymarket/clob-client";
  import { BuilderConfig } from "@polymarket/builder-signing-sdk";

  // Point to your signing server
  const builderConfig = new BuilderConfig({
    remoteBuilderConfig: { 
      url: "https://your-server.com/sign"
    }
  });

  // Or with optional authorization token
  const builderConfigWithAuth = new BuilderConfig({
    remoteBuilderConfig: { 
      url: "https://your-server.com/sign", 
      token: "your-auth-token" 
    }
  });

  const client = new ClobClient(
    "https://clob.polymarket.com",
    137,
    signer, // ethers v5.x EOA signer
    creds, // User's API Credentials
    2, // signatureType for the Safe proxy wallet
    funderAddress, // Safe proxy wallet address
    undefined, 
    false,
    builderConfig
  );

  // Orders automatically use the signing server
  const order = await client.createOrder({
    price: 0.40,
    side: Side.BUY,
    size: 5,
    tokenID: "YOUR_TOKEN_ID"
  });

  const response = await client.postOrder(order);
  ```

  ```python Python theme={null}
  from py_clob_client.client import ClobClient
  from py_builder_signing_sdk import BuilderConfig, RemoteBuilderConfig

  # Point to your signing server
  builder_config = BuilderConfig(
      remote_builder_config=RemoteBuilderConfig(
          url="https://your-server.com/sign"
      )
  )

  # Or with optional authorization token
  builder_config_with_auth = BuilderConfig(
      remote_builder_config=RemoteBuilderConfig(
          url="https://your-server.com/sign",
          token="your-auth-token"
      )
  )

  client = ClobClient(
      host="https://clob.polymarket.com",
      chain_id=137,
      key=private_key,
      creds=creds,  # User's API Credentials
      signature_type=2,  # signatureType for the Safe proxy wallet
      funder=funder_address,  # Safe proxy wallet address
      builder_config=builder_config
  )

  # Orders automatically use the signing server
  order = client.create_order({
      "price": 0.40,
      "side": "BUY",
      "size": 5,
      "token_id": "YOUR_TOKEN_ID"
  })

  response = client.post_order(order)
  ```
</CodeGroup>

### Troubleshooting

<AccordionGroup>
  <Accordion title="Invalid Signature Errors">
    **Error:** Client receives invalid signature errors

    **Solution:**

    1. Verify the request body is passed correctly as JSON
    2. Check that `path`, `body`, and `method` match what the client sends
    3. Ensure your server and client use the same Builder API credentials
  </Accordion>

  <Accordion title="Missing Credentials">
    **Error:** `Builder credentials not configured` or undefined values

    **Solution:** Ensure your environment variables are set:

    * `POLY_BUILDER_API_KEY`
    * `POLY_BUILDER_SECRET`
    * `POLY_BUILDER_PASSPHRASE`
  </Accordion>
</AccordionGroup>
Sign orders locally when you control the entire order placement flow.
**How it works:**

1. Your system creates and signs orders on behalf of users
2. Your system uses Builder API credentials locally to add headers
3. Complete signed order is sent directly to the CLOB

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { ClobClient } from "@polymarket/clob-client";
  import { BuilderConfig, BuilderApiKeyCreds } from "@polymarket/builder-signing-sdk";

  // Configure with local builder credentials
  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, // ethers v5.x EOA signer
    creds, // User's API Credentials
    2, // signatureType for the Safe proxy wallet
    funderAddress, // Safe proxy wallet address
    undefined, 
    false,
    builderConfig
  );

  // Orders automatically include builder headers
  const order = await client.createOrder({
    price: 0.40,
    side: Side.BUY,
    size: 5,
    tokenID: "YOUR_TOKEN_ID"
  });

  const response = await client.postOrder(order);
  ```

  ```python Python theme={null}
  import os
  from py_clob_client.client import ClobClient
  from py_builder_signing_sdk import BuilderConfig, BuilderApiKeyCreds

  # Configure with local builder credentials
  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=creds,  # User's API Credentials
      signature_type=2,  # signatureType for the Safe proxy wallet
      funder=funder_address,  # Safe proxy wallet address
      builder_config=builder_config
  )

  # Orders automatically include builder headers
  order = client.create_order({
      "price": 0.40,
      "side": "BUY",
      "size": 5,
      "token_id": "YOUR_TOKEN_ID"
  })

  response = client.post_order(order)
  ```
</CodeGroup>

<Warning>
  Never commit credentials to version control. Use environment variables or a secrets manager.
</Warning>

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
With **local signing**, the SDK constructs and attaches these headers automatically. With **remote signing**, your server must return these headers (see Server Implementation above), and the SDK attaches them to the request.

Next Steps

Learn how to configure and use the Relay Client too! Explore the complete CLOB client reference