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.
Every impersonated request must include both headers:
| Header | Value | Description |
|---|
X-API-Key | pk_live_YOUR_BUILDER_KEY | Your builder API key |
X-Builder-Customer-Id | a1b2c3d4-... | 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
| Field | Source | Purpose |
|---|
| Your user ID | Your auth system | Identify the user in your app |
customer_id | POST /builder/onboard response | Impersonate via X-Builder-Customer-Id |
external_id | You choose this | Your internal ID (idempotency key) |
api_key | POST /builder/onboard response | Not 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
| Code | Meaning |
|---|
401 | Missing or invalid X-API-Key |
403 | X-Builder-Customer-Id requires a builder account |
403 | End-user not found or not owned by this builder |
400 | X-Builder-Customer-Id cannot be used with Bearer token auth |
429 | QPS pool exhausted |