Builder Integration Guide
Build prediction market interfaces on top of the Oracle platform. Third-party frontends ("builders") can embed markets, route orders, and earn creator fees.
Architecture
Your Frontend --> Oracle Signer --> Oracle Gateway --> Engine
|
Signs orders REST API Matching
Manages keys
|
Oracle Deposit --> Proxy Wallet --> Vault
|
Deposit addresses USDC custody Settlement
The Oracle Signer is a signing server that handles Ed25519 key management so your frontend never touches private keys.
Quick Start
1. Get an API Key
curl -X POST ${SIGNER_URL}/v1/admin/builders \
-H "X-Admin-Key: ${ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{"name": "My Trading App"}'
Response:
{"api_key": "bld_a1b2c3d4e5f6...", "name": "My Trading App"}
2. Create a User Key
When a user registers on your platform, create a delegated signing keypair:
curl -X POST ${SIGNER_URL}/v1/keys \
-H "X-Api-Key: bld_a1b2c3d4e5f6..." \
-H "Content-Type: application/json" \
-d '{"user_id": "user-123"}'
Response:
{"user_id": "user-123", "public_key": "7yQ3mH9a..."}
The public_key is the user's trading address. Store the mapping user_id <-> public_key in your database.
3. Fund the User
Get a deposit address for the user's keypair:
curl -X POST ${SIGNER_URL}/v1/deposit/address \
-H "X-Api-Key: bld_a1b2c3d4e5f6..." \
-H "Content-Type: application/json" \
-d '{"user": "7yQ3mH9a...", "chain": "solana"}'
Response includes the USDC deposit address. Have users send USDC there.
4. Place Orders
Submit orders through the signer — it signs and forwards to the gateway:
curl -X POST ${SIGNER_URL}/v1/submit \
-H "X-Api-Key: bld_a1b2c3d4e5f6..." \
-H "Content-Type: application/json" \
-d '{
"user": "7yQ3mH9a...",
"market_id": "abc123...",
"side": "buy",
"outcome": "yes",
"price": 6500,
"size": 100,
"order_type": "gtc",
"nonce": 1
}'
The signer handles the Ed25519 signature. The response is the same as POST /v1/orders on the gateway.
5. Read Market Data
Query the gateway directly — no API key needed for read endpoints:
# All markets with prices
curl ${GATEWAY_URL}/v1/markets
# All events (multi-outcome groups)
curl ${GATEWAY_URL}/v1/events
# Order book
curl ${GATEWAY_URL}/v1/markets/${MARKET_ID}/book
# Trade history
curl ${GATEWAY_URL}/v1/markets/${MARKET_ID}/trades?limit=50
# Candles
curl ${GATEWAY_URL}/v1/markets/${MARKET_ID}/candles?interval=5m
# User balance
curl ${GATEWAY_URL}/v1/balance/${PUBLIC_KEY}
# User position
curl ${GATEWAY_URL}/v1/position/${MARKET_ID}/${PUBLIC_KEY}
# User trade history
curl ${GATEWAY_URL}/v1/trades/${PUBLIC_KEY}
Signer API Reference
All builder endpoints require X-Api-Key header.
| Endpoint | Method | Description |
|---|---|---|
/v1/keys |
POST | Get or create delegated keypair for a user |
/v1/sign |
POST | Sign an order message (returns signature only) |
/v1/submit |
POST | Sign and submit order to gateway |
/v1/deposit/address |
POST | Get deposit address via deposit service |
/health |
GET | Health check |
Admin Endpoints
Require X-Admin-Key header.
| Endpoint | Method | Description |
|---|---|---|
/v1/admin/builders |
POST | Register new builder |
/v1/admin/builders |
GET | List all builders |
Cancel Orders
Use the gateway directly with the user's public key:
# Cancel single order
curl -X POST ${GATEWAY_URL}/v1/orders/cancel \
-d '{"market_id": "abc...", "order_id": 42, "user": "7yQ...", "signature": "..."}'
# Cancel all orders for user
curl -X POST ${GATEWAY_URL}/v1/orders/cancel-all \
-d '{"user": "7yQ...", "market_id": "abc...", "signature": "deadbeef...", "nonce": 1}'
For cancel operations, use the signer's /v1/sign endpoint to get the signature, then submit to the gateway yourself.
Real-Time Data
Connect to the WebSocket server directly:
const ws = new WebSocket(`${WS_URL}/v1/ws`)
ws.onopen = () => {
// Subscribe to book updates (includes yes/no prices)
ws.send(JSON.stringify({ action: 'subscribe', channel: `book:${marketId}` }))
// Subscribe to trades
ws.send(JSON.stringify({ action: 'subscribe', channel: `trades:${marketId}` }))
// Subscribe to user-specific fills
ws.send(JSON.stringify({ action: 'subscribe', channel: `user:${publicKey}` }))
}
See WebSocket Guide for full event documentation.
Creating Markets
Builders can create markets/events via the gateway (requires admin key in production):
# Binary market (Yes/No)
curl -X POST ${GATEWAY_URL}/v1/events \
-H "X-Admin-Key: ${ADMIN_KEY}" \
-d '{
"title": "Will BTC reach $200k?",
"category": "crypto",
"outcomes": ["Yes"],
"resolution_source": "price_oracle",
"expiry": 1798761600,
"creator": "7yQ..."
}'
# Multi-outcome event
curl -X POST ${GATEWAY_URL}/v1/events \
-H "X-Admin-Key: ${ADMIN_KEY}" \
-d '{
"title": "Who will win the Super Bowl?",
"category": "sports",
"outcomes": ["Chiefs", "Eagles", "49ers", "Other"],
"resolution_source": "api_oracle",
"expiry": 1798761600,
"creator": "7yQ..."
}'
Market creators earn 10% of all trading fees collected on their markets.
Rate Limiting
Requests are rate-limited via a token bucket keyed by API key (IP as fallback). Default 10 req/s, configurable via RATE_LIMIT_RPS env on the signer. Exceeding the limit returns HTTP 429 with a JSON error ({"error": "rate limit exceeded"}). Admin-authenticated endpoints (via X-Admin-Key) bypass the limit.
Security Model
- API keys identify and rate-limit builders
- Delegated keypairs are managed by the signer server — builders never see private keys
- The signer cannot withdraw funds — it only signs order messages
- Users deposit USDC to their own proxy wallets on-chain
- The signer is stateless for order signing (keys are persisted to disk)
Service URLs
| Service | Purpose | Auth |
|---|---|---|
| Gateway | REST API (markets, orders, balances) | Public reads, admin writes |
| WebSocket | Real-time market data | Public |
| Signer | Order signing for builders | X-Api-Key |
| Deposit | Funding (deposit/withdraw) | Public |
| Swagger | Interactive API docs | {gateway_url}/swagger-ui/ |