Partner Attribution
This guide explains how partners can integrate with Lighter programmatically to earn additional fees for trades executed through their applications, or just for tracking purposes. The program is permissionless, allowing any account index to be used to collect fees, including subaccounts.
Definitions
Partner: You, the integrator building on top of Lighter.
Client: Your user, or customer, whose transactions you send on their behalf. Both standard and premium accounts are accepted.
Requirements
Trades containing partner attribution attributes with non-zero integrator fees will require the client submitting them to be on a Plus or Premium account type. To check the account type of a client, you can use the accountLimits endpoint. To change account type, use changeAccountTier. Zero-fee attribution (tracking only) works on any account type, including Standard.
Integrator Approval
Before you can append partner attributes to client transactions, they must submit a ApproveIntegrator transaction. Approving an account index associated with a different L1 address requires an L1 signature. However, if the account index is associated with the same L1 address, or fees are zero, only an L2 signature is needed. This transaction authorizes you to charge additional taker/maker fees on trades originating from orders created through your platform, as defined via the systemConfig endpoint.
At any point in time, there can only be a maximum of 4 approved Partners per Client.
Example
client.approve_integrator(
eth_private_key=STRING,
integrator_account_index=INTEGER,
max_perps_taker_fee=INTEGER,
max_perps_maker_fee=INTEGER,
max_spot_taker_fee=INTEGER,
max_spot_maker_fee=INTEGER,
approval_expiry=INTEGER # in ms
)client.approve_integrator(
eth_private_key="",
integrator_account_index=1234,
max_perps_taker_fee=1000, # 10 bps
max_perps_maker_fee=1000, # 10 bps
max_spot_taker_fee=1000, # 10 bps
max_spot_maker_fee=1000, # 10 bps
approval_expiry=1775518466000 # in ms
)const tx = check(lighter.SignApproveIntegrator(
PARTNER_ACCOUNT_INDEX,
1000, // maxPerpsTakerFee (1000 = 10 bps)
1000, // maxPerpsMakerFee
1000, // maxSpotTakerFee
1000, // maxSpotMakerFee
Date.now() + 365 * 24 * 3600e3, // approvalExpiry, unix ms
0, await nextNonce(), API_KEY_INDEX, CLIENT_ACCOUNT_INDEX,
));
// If the partner account belongs to a different L1 address and fees > 0,
// the client's wallet must sign tx.messageToSign → txInfo.L1SigYou can find the full Python example here. The TypeScript example uses the WASM signer from the TypeScript quickstart; see When an L1 signature is required. To revoke an integrator before the allowance expires, you can send another ApproveIntegrator request setting all fees to zero, requiring just an L2 signature.
Fields Explanation
IntegratorAccountIndex: Partner's account index. All partner fees collected from client trades will be credited to this account. For perpetual markets, the fees are paid and credited in USDC (perps). For spot markets, the fees are paid and credited in the received asset (e.g. buying spot ETH means the Client pays fees in ETH directly).
Max Fees: These values define the maximum fees you are allowed to charge your client.
Fees are calculated as:
fee(bps) = trade_size × (fee_value / 1e6)
Example:
MaxPerpsTakerFee = 500
500 / 1e6 = 0.0005 = 5 basis points
This means you can charge up to 5 bps of the trade quote for each perpetual taker order.
System-wide Maximums
Lighter enforces global maximum fee limits. If you submit an approval transaction exceeding these limits, the transaction will fail. Current limits can be checked via the systemConfig endpoint.
ApprovalExpiry
The timestamp when the integrator approval expires in a form of Unix timestamp in milliseconds. After this time, the partner must obtain approval again from the client.
The maximum value you can send is equivalent to 2^48-1.
Creating Orders for Your Client
Once the integrator approval is successfully submitted, you can begin sending transactions for the client and collecting partner fees.
When creating orders, include the following fields:
IntegratorAccountIndex: INTEGER # the partner account index, where integrator fees will accrue
IntegratorMakerFee: INTEGER # fee the partner wants to charge for maker trades
IntegratorTakerFee: INTEGER # fee the partner wants to charge for taker tradesThese fees must not exceed the maximum values defined during the approval step. The same fields exist on modify and grouped orders.
Non-zero partner fees can't be combined with custom self-trade preventionIf an order sets a non-zero
integratorTakerFeeorintegratorMakerFeetogether with any self-trade mode other than the default (0, 0: expire maker, same account index), it is rejected with21159"self-trade specifications are not allowed when there are non-zero fees". Zero-fee attribution (tracking only) works with any self-trade mode.
Example: Creating an Order
client.create_order(
market_index=0,
client_order_index=0, # bound to 2^48-1
base_amount=1000, # decimals as described in the orderBookDetails endpoint
price=4050_00, # decimals as described in the orderBookDetails endpoint
is_ask=True, # sell
order_type=client.ORDER_TYPE_LIMIT,
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
reduce_only=False,
trigger_price=0,
integrator_account_index=integrator_account_index,
integrator_taker_fee=integrator_taker_fee,
integrator_maker_fee=integrator_maker_fee,
nonce=nonce,
api_key_index=api_key_index,
)lighter.SignCreateOrder(
marketIndex, clientOrderIndex, baseAmount, price, isAsk, orderType, tif,
reduceOnly, triggerPrice, orderExpiry,
PARTNER_ACCOUNT_INDEX, // integratorAccountIndex
500, // integratorTakerFee (5 bps) – must be ≤ approved max
200, // integratorMakerFee (2 bps)
0, 0, 0, nonce, API_KEY_INDEX, CLIENT_ACCOUNT_INDEX,
);You can find the full Python example here.
Design tips
- Show your fee clearly in the order ticket.
- Request an approval expiry that matches your product (e.g. 1 year) and re-prompt before it lapses.
- Use a dedicated sub-account as your integrator account to keep revenue separate.
- Track attributed volume and fees with partnerStats.
Updated 13 days ago
