Builder Program
A builder is any application that submits user orders to the Openfish CLOB. Whether you have built a trading interface, a portfolio aggregator, a copy-trading service, or any product that lets users place prediction market trades, the Builder Program provides the infrastructure you need.
Program Benefits
Section titled “Program Benefits”| Benefit | Description |
|---|---|
| Relayer Access | Gasless wallet deployment, token approvals, and CTF operations on behalf of your users |
| Volume Attribution | Every order includes your builder_id, linking volume to your account |
| Builder Fees | Collect a fee on orders routed through your application |
| Support | Dedicated Telegram channel and engineering assistance (Verified tier and above) |
How It Works
Section titled “How It Works”- User places order — A user submits an order through your application.
- Sign request — Your backend signs the request with Builder API credentials.
- Submit to CLOB — The order is sent to
POST /builder/orderwith theOPENFISH_BUILDER_IDheader for attribution. - Trade execution — Openfish matches the order. If the user operates a Safe or Proxy wallet, the relayer covers gas costs.
- Volume attribution — The resulting trade is credited to your builder account.
Order Attribution
Section titled “Order Attribution”Every builder order must carry the OPENFISH_BUILDER_ID header. The server extracts it and records it alongside the order and any resulting trades:
// From openfish-clob-server builder_routes.rsstruct BuilderHeaders { pub builder_id: String,}
impl BuilderHeaders { fn extract(headers: &HeaderMap) -> Result<Self, AppError> { let builder_id = headers .get("OPENFISH_BUILDER_ID") .or_else(|| headers.get("poly_builder_id")) .and_then(|v| v.to_str().ok()) .unwrap_or("") .to_owned(); if builder_id.is_empty() { return Err(AppError::BadRequest( "OPENFISH_BUILDER_ID header required".to_owned(), )); } Ok(Self { builder_id }) }}Builder Endpoints
Section titled “Builder Endpoints”| Method | Path | Description |
|---|---|---|
POST | /builder/order | Submit an order with builder attribution |
POST | /builder/cancel | Cancel an order with builder attribution |
POST | /auth/builder-api-key | Create a new builder API key |
GET | /auth/builder-api-key | List your builder API keys |
DELETE | /auth/builder-api-key | Revoke a builder API key |
Submitting a Builder Order
Section titled “Submitting a Builder Order”A builder order uses the same payload format as a standard CLOB order, but goes through the builder endpoint and includes the attribution header.
use reqwest::Client;use serde_json::json;
let response = Client::new() .post("https://api.openfish.fun/builder/order") .header("OPENFISH_BUILDER_ID", "my-trading-app") .header("OPENFISH_API_KEY", &api_key) .header("OPENFISH_SECRET", &secret) .header("OPENFISH_PASSPHRASE", &passphrase) .header("OPENFISH_TIMESTAMP", ×tamp) .header("OPENFISH_SIGNATURE", &signature) .json(&json!({ "order": { "tokenId": token_id, "maker": user_address, "side": "BUY", "makerAmount": "500000", "takerAmount": "1000000", "signature": order_signature, "expiration": "0", }, "orderType": "GTC", })) .send() .await?;The response confirms attribution with the builder_id field:
{ "orderID": "a1b2c3d4-...", "status": "LIVE", "success": true, "builder_id": "my-trading-app", "tradeIds": []}Getting Started
Section titled “Getting Started”- Generate API credentials — Create a standard L2 API key, then issue a builder API key through
POST /auth/builder-api-key. See API Keys. - Configure attribution — Include the
OPENFISH_BUILDER_IDheader on every order submission. - Route orders — Submit orders through
POST /builder/orderrather than the standardPOST /orderendpoint. - Track performance — Query builder trades and volume through the CLOB API.