Skip to main content

How builder auth works

Builder authentication uses impersonation. Your builder API key authenticates the request, and the X-Builder-Customer-Id header tells Parsec which end-user the request is for.
Your App                          Parsec API
────────                          ──────────
User action in your UI


Your backend looks up               X-API-Key: pk_live_BUILDER_KEY
the user's Parsec customer_id  ───► X-Builder-Customer-Id: CUSTOMER_ID
        │                           POST /orders?exchange=polymarket

Response returned to user      ◄──  { "id": "order_123", "status": "open" }
Your users never see your builder API key. Authentication happens entirely on your backend. Your frontend talks to your backend, and your backend talks to Parsec.

Required headers

Every impersonated request must include both headers:
HeaderValueDescription
X-API-Keypk_live_YOUR_BUILDER_KEYYour builder API key
X-Builder-Customer-Ida1b2c3d4-...The end-user’s customer_id
curl -X POST "https://api.parsecapi.com/api/v1/orders?exchange=polymarket" \
  -H "X-API-Key: pk_live_YOUR_BUILDER_KEY" \
  -H "X-Builder-Customer-Id: a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Content-Type: application/json" \
  -d '{
    "market_id": "0x...",
    "outcome": "Yes",
    "side": "buy",
    "price": 0.55,
    "size": 100
  }'

Typical app architecture

┌──────────────────────────┐
│      Your Frontend       │
│  (React, Next.js, etc.)  │
│                          │
│  User logs in with your  │
│  own auth (email, OAuth) │
└────────────┬─────────────┘
             │ Your own auth token

┌──────────────────────────┐
│      Your Backend        │
│  (Node, Python, etc.)    │
│                          │
│  Maps your user ID ──►   │
│  Parsec customer_id      │
│                          │
│  Stores mapping in your  │
│  database                │
└────────────┬─────────────┘
             │ X-API-Key + X-Builder-Customer-Id

┌──────────────────────────┐
│      Parsec API          │
│                          │
│  Validates builder key   │
│  Verifies user ownership │
│  Routes to exchange      │
└──────────────────────────┘

What you store in your database

FieldSourcePurpose
Your user IDYour auth systemIdentify the user in your app
customer_idPOST /builder/onboard responseImpersonate via X-Builder-Customer-Id
external_idYou choose thisYour internal ID (idempotency key)
api_keyPOST /builder/onboard responseNot needed for impersonation (optional backup)
You do not need to store or distribute end-user API keys. All requests go through your backend using your builder key + impersonation header. End-user API keys exist as a fallback for advanced use cases where users need direct Parsec access.

Per-request credentials

For users who don’t want credentials stored on Parsec, pass exchange credentials per-request via the X-Exchange-Credentials header (base64-encoded JSON). Create the user without onboard and include this header on every impersonated request:
# base64 encode: {"clob_api_key":"...","clob_api_secret":"...","clob_api_passphrase":"..."}
curl -X POST "https://api.parsecapi.com/api/v1/orders?exchange=polymarket" \
  -H "X-API-Key: pk_live_YOUR_BUILDER_KEY" \
  -H "X-Builder-Customer-Id: CUSTOMER_ID" \
  -H "X-Exchange-Credentials: eyJjbG9iX2FwaV9rZXkiOi..." \
  -H "Content-Type: application/json" \
  -d '{ "market_id": "0x...", "outcome": "Yes", "side": "buy", "price": 0.55, "size": 100 }'

Error responses

CodeMeaning
401Missing or invalid X-API-Key
403X-Builder-Customer-Id requires a builder account
403End-user not found or not owned by this builder
400X-Builder-Customer-Id cannot be used with Bearer token auth
429QPS pool exhausted