Builder Codes
Earn a share of trading fees by directing order flow to RISEx
Overview
Builder codes let front-end applications and integrators earn a share of trading fees from the order flow they direct to RISEx. Similar to a referral system, but designed for builders creating trading interfaces, bots, and aggregators.
A builder attaches its builder_id and a small fee to the orders it submits on a trader's behalf. When those orders fill, the builder fee is charged to the trader and paid to the builder's fee_recipient.
builder_fee_bps is denominated in 1/100th of a basis point (RISEx uses a fee denominator of 1,000,000). So builder_fee_bps = 100 is 1 bps (0.01% of notional) and builder_fee_bps = 50 is 0.5 bps. Builder fees are charged in addition to standard RISEx protocol fees, not subtracted from them.
How it works
- Register your builder code (permissionless, no approval needed) to get a
builder_id, providing thefee_recipientthat receives your fees. Confirm it appears inGET /v1/builders. - The trader registers an API wallet (a session key), so you are not prompting their main wallet for every order.
- The trader approves your fee once, which caps the fee your
builder_idcan charge them. - You place orders carrying your
builder_idandbuilder_fee_bps. Fees accrue to yourfee_recipient.
Integration steps
1. Register your builder code
Builder registration is permissionless: any integrator can register directly, with no approval from the RISEx team. Call registerBuilderCode(feeRecipient) on the FeeManager contract, passing the address that should receive your builder fees. It returns your builder_id.
| Contract | FeeManager 0x11541dc387b9C307043ea732127DF92b80bab52b |
| Function | registerBuilderCode(address feeRecipient) returns (uint16 builderId) |
Confirm your builder appears in GET /v1/builders, then attach the returned builder_id to every order you submit.
2. Register an API wallet (session key)
Generate a session key for the trader and register it. The trader signs a RegisterSigner message once with their main wallet; the session key signs everything after that.
See Register Signer for the full flow. POST /v1/auth/register-signer.
The trader's wallet must be on RISE (chainId 4153) to produce a valid signature.
3. Approve the builder fee (one time per trader and builder)
The trader authorizes a maximum fee your builder_id can charge them. This is signed by the session key inside a VerifyWitness permit (see Creating Permit Params).
POST /v1/orders/builder-fee/approve
The action hash the permit wraps is:
actionHash = keccak256(abi.encode(
keccak256("RISE_APPROVE_BUILDER_FEE_V1"),
uint16(builderId),
uint16(maxFeeBps)
));4. Place orders with your builder code
Attach builder_id and builder_fee_bps to each order (see Place Order for the base flow). Setting builder_id != 0 selects the V3 order layout, which includes the fee word in the signed action hash:
actionHash = keccak256(abi.encode(
typeHash, uint8(flags), uint88(orderData),
uint16(builderId), uint16(builderFeeBps),
uint64(clientOrderId), uint16(ttlUnits)
));The builderFeeBps word sits right after builderId. When builder_id == 0, the older layout is used and there is no fee word.
Request body
{
"market_id": 1,
"size_steps": 200,
"price_ticks": 0,
"side": 0,
"post_only": false,
"reduce_only": false,
"stp_mode": 0,
"order_type": 0,
"time_in_force": 3,
"builder_id": 1,
"builder_fee_bps": 100,
"client_order_id": "0",
"ttl_units": 0,
"permit": {
"account": "0x...",
"signer": "0x...",
"nonce_anchor": 0,
"nonce_bitmap_index": 0,
"deadline": 0,
"signature": "<base64>"
}
}Common errors
| Error | Cause | Fix |
|---|---|---|
SignerNotAuthorized(address) | The signed hash does not match what the backend recomputed. Most often builder_fee_bps was nested in the permit instead of top-level, or the API wallet is not registered. | Put builder_fee_bps at the top level. Confirm the session key is registered. |
Provided chainId "4153" must match the active chainId "..." | The wallet was on a different network when signing. | Switch the wallet to RISE (chainId 4153) before signing. |
BelowMinOrderSize(uint256) | Order size is under the market minimum. | Use at least the market's min_order_size from GET /v1/markets (for example BTC is 0.00015). |
Verifying a fill
After an order fills, GET /v1/trade-history?account={account} returns the fill with the fee charged. The builder portion is included in the total fee and paid to your fee_recipient.
For the complete endpoint reference, see the Full API Documentation.