For the complete documentation index, see llms.txt. This page is also available as Markdown.

Placing orders

To charge a builder fee, add two fields to the order and include them in the order signature.

Field
Type
Example

builder_id

string

"builder_0123456789abcdef"

builder_fee_rate

decimal string, at most 6 decimals

"0.0003" (3 bps)

The same fields work on REST POST /orders, POST /orders/{order_id} (edit), batch orders, and the websocket create_order / edit_order operations.

Signing

Builder orders are signed with the account's API signing key, like any other order. The EIP-712 primary type is still Order, with two extra fields at the end:

Order(address maker,bool isBuy,uint256 limitPrice,uint256 amount,uint256 salt,uint256 instrument,uint256 timestamp,string builderId,uint256 builderFeeRate)
  • builderId is your builder_id string.

  • builderFeeRate is the raw 6-decimal integer: "0.0003" is signed as 300.

  • The domain is the same as for normal orders.

If builder_id is present, the signature must be over this type. A signature over the normal Order type is rejected.

Example (REST)

{
  "maker": "0xBuilderUserAddress",
  "is_buy": true,
  "instrument": 1,
  "limit_price": "2700000000",
  "amount": "1000000",
  "salt": "123456789",
  "timestamp": 1790000000,
  "signature": "0x...",
  "post_only": false,
  "reduce_only": false,
  "builder_id": "builder_0123456789abcdef",
  "builder_fee_rate": "0.0003"
}

With the Python SDK:

Supported orders

Builder fields are accepted on signed limit and market orders for perpetuals and options.

Option orders with builder fields are rejected with BUILDER_NOT_SUPPORTED while the options builder settings are unset (max_fee_rate_options or option_premium_cap is null in GET /builder-config).

Cancelling and editing

Cancels (DELETE /orders/{order_id}, DELETE /orders-all, DELETE /orders (up to 10 order IDs), websocket cancel_order / cancel_all_orders) work the same with or without a builder:

  • They take no builder fields and need only the user's API key, no signature.

  • They are free. A builder fee is charged only when an order fills; cancelling an unfilled order, or the unfilled rest of a partially filled order, charges nothing.

  • A cancel applies to any of the user's orders, not only those your builder placed. DELETE /orders-all cancels every order in the chosen scope, including orders the user placed in the Aevo app or through other apps.

Edits (POST /orders/{order_id}, websocket edit_order) replace the order with a new signed order. Send builder_id and builder_fee_rate again on every edit, and include them in the new order's signature. If you leave them out, the edited order has no builder attribution and its fills pay no builder fee.

Perpetuals vs options

You send the builder fee the same way on both: the same two fields, the same decimal format, and the same signed Order type. Only the instrument differs. What changes is how Aevo applies the rate when the order fills, and which protocol cap it is checked against.

Perpetual order
Option order

Fields

builder_id, builder_fee_rate

builder_id, builder_fee_rate (same)

builder_fee_rate format

Decimal string, e.g. "0.0003"

Decimal string, e.g. "0.0003" (same)

Signed as

Raw integer, e.g. 300

Raw integer, e.g. 300 (same)

Rate is applied to

Trade price × contracts

Index price × contracts, capped at option_premium_cap × premium × contracts

Protocol cap checked

max_fee_rate_perps

max_fee_rate_options

For an option order:

  • builder_fee_rate is a rate on index notional, not on the premium. "0.0003" means 3 bps of index price × contracts, not 0.03% of the option price you are quoting in limit_price.

  • Don't calculate the premium cap yourself. Send the rate; Aevo applies the premium cap on each fill and charges the smaller amount.

  • Never send a fee amount. Only the rate is sent. The amount is worked out per fill.

  • Stay at or below max_fee_rate_options (3 bps), which is lower than the perpetuals cap (5 bps) and can be lower than the user's approved maximum. Above it, the order is rejected with BUILDER_FEE_EXCEEDS_AEVO_LIMIT.

Sample payloads

Both are POST /orders bodies. Only instrument and limit_price differ; the builder fields are identical. Look up instrument IDs with GET /markets; the IDs below are examples. limit_price and amount use 6 decimals.

Perpetual

Buy 1 ETH-PERP at $2,700 with a 3 bps builder fee:

Builder fee on a full fill: 0.0003 × 2,700 × 1 = $0.81.

Option

Buy 1 ETH call at a $20 premium with a 3 bps builder fee (ETH index $2,700, option premium cap 5%):

Builder fee on a full fill: min(0.0003 × 2,700 × 1, 0.05 × 20 × 1) = min(0.81, 1.00) = $0.81.

At a $5 premium, the same order pays min(0.81, 0.25) = $0.25: the premium cap applies.

In both cases the signature is over the builder Order type with builderFeeRate = 300 (see Signing). See Perpetuals vs Options Fees for more examples.

Checks

Checks run when the order is submitted, so an order that breaks a rule is rejected straight away and never rests on the book:

  1. The builder exists and is ACTIVE.

  2. The user has approved the builder.

  3. builder_fee_rate ≤ the user's approved max_fee_rate.

  4. builder_fee_rate ≤ the protocol cap: max_fee_rate_perps (5 bps) for perpetuals, max_fee_rate_options (3 bps) for options.

The same rules are checked again on every fill. If one no longer holds (for example the user revoked), the fill still executes with a builder fee of 0 and keeps your builder_id.

Maker and taker

The builder fee applies whether your order is the maker or the taker. A taker order that fills against several makers is charged on each fill.

Where the fee appears

Each fill in the user's trade history, trade CSV and the websocket fills channels carries builder_id, builder_fee_rate and builder_fee (USDC). The builder fee is separate from fee, which is Aevo's trading fee.

Errors

Code
Meaning

BUILDER_NOT_APPROVED

The user hasn't approved this builder, or revoked.

BUILDER_FEE_EXCEEDS_USER_LIMIT

builder_fee_rate is above the user's approved maximum.

BUILDER_FEE_EXCEEDS_AEVO_LIMIT

builder_fee_rate is above the protocol cap for this instrument type.

BUILDER_NOT_ACTIVE

The builder is suspended or disabled.

BUILDER_NOT_SUPPORTED

Builder fields on an unsupported order type or instrument.

BUILDER_INVALID_FEE_RATE

builder_fee_rate isn't a decimal with at most 6 decimals.

BUILDER_INVALID_ID

builder_id is malformed.

BUILDER_NOT_FOUND

Unknown builder_id.

Last updated

Was this helpful?