Authentication
Parti supports two authentication methods for programmatic access:
Method 1: Builder API Key (Recommended)
Register a builder API key via wallet signature. The key bypasses per-order Ed25519 signing — send the key with every request instead.
Self-Service Registration
# 1. Sign the registration message with your wallet
# Message: "Parti Builder Registration\nUser: {pubkey}\nTimestamp: {ts}"
# Or: "Parti Session\nUser: {pubkey}\nTimestamp: {ts}"
# 2. Register (returns API key + sets HTTP-only session cookie)
POST /v1/builders/register
{
"user": "<base58 pubkey>",
"name": "my-bot",
"signature": "<hex-encoded Ed25519 signature>",
"timestamp": 1777500000
}
# Response:
{
"api_key": "uuid-v4-key",
"wallet": "<pubkey>",
"name": "my-bot"
}
Using the Key
Include builder_api_key in order/cancel request bodies:
{
"market_id": "...",
"user": "<pubkey>",
"side": "buy",
"outcome": "yes",
"price": 6000,
"size": 100,
"order_type": "gtc",
"signature": "00000...00000",
"nonce": 1234567890,
"builder_api_key": "your-api-key"
}
The signature can be a placeholder (64 zero bytes hex) when using a builder API key — the key proves wallet ownership.
Session Cookie (Frontend)
The /v1/builders/register endpoint also sets an HTTP-only parti_session cookie. If your client sends cookies (credentials: 'include'), you don't need builder_api_key in the body — the cookie handles auth automatically.
- Duration: 7 days
- Scope: HttpOnly, Secure, SameSite=None
- Renewal: Call register again after expiry
Rate Limits
- 600 orders/min per builder API key
- 10 requests/sec per IP (burst 50) on public endpoints
- Internal services bypass via
X-Internal-Keyheader
Method 2: HMAC Signer (Legacy)
For bots using the dedicated signer service, endpoints are protected by HMAC-SHA256 request signatures.
| Header | Required on | Description |
|---|---|---|
X-Api-Key |
All builder endpoints | Your builder API key (bld_...) |
X-Timestamp |
/v1/submit, /v1/trades |
Current Unix timestamp (seconds) |
X-Signature |
/v1/submit, /v1/trades |
HMAC-SHA256 signature (hex) |
Signing
import hmac, hashlib, time, json, requests
API_KEY = "bld_a1b2c3..."
API_SECRET = "deadbeef1234..." # hex-encoded 32 bytes
SIGNER_URL = "https://signer.parti-oracle.pbcapps.dev"
def signed_request(method, path, body=None):
timestamp = str(int(time.time()))
body_str = json.dumps(body) if body else ""
message = timestamp + body_str
signature = hmac.new(
bytes.fromhex(API_SECRET),
message.encode(),
hashlib.sha256
).hexdigest()
headers = {
"X-Api-Key": API_KEY,
"X-Timestamp": timestamp,
"X-Signature": signature,
"Content-Type": "application/json",
}
return requests.request(method, SIGNER_URL + path,
headers=headers, json=body)
Replay Protection
Requests are rejected if the timestamp is more than 60 seconds old. Keep your server clock synchronized (NTP recommended).
Security Notes
- Never expose API keys or secrets in client-side code
- All signing should happen on your backend
- Use HTTPS for all requests
- Builder API keys are tied to a specific wallet address — they cannot be used for other wallets
- Withdrawals always require a real wallet signature (separate from session/builder auth)