> For the complete documentation index, see [llms.txt](https://docs.lighter.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lighter.xyz/developers/integration-guides/partner-attribution.md).

# Partner Attribution

{% hint style="info" %}
**Lighter on Robinhood Chain**

On RH, perp integrator fees are paid and credited in USDG. See [Lighter on Robinhood Chain](/developers/robinhood-chain/overview.md) for everything that differs on RH.
{% endhint %}

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/Advanced 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/Advanced [account type](/developers/reference/account-types.md). To check the account type of a client, you can use the [accountLimits](https://docs.lighter.xyz/api/account) endpoint. To change account type, use [changeAccountTier](https://docs.lighter.xyz/api/account). 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](https://docs.lighter.xyz/api/system) endpoint.

Binary options use the client's **spot** approval limits (`max_spot_taker_fee`, `max_spot_maker_fee`) and the system-wide spot caps. Their integrator fees are scaled by the trade price; see [Binary options: Partner attribution](/developers/binary-options/partner-attribution.md).

At any point in time, there can only be a maximum of 4 approved Partners per Client.

### Example

{% tabs %}
{% tab title="Python: signature" %}

```python
tx_info, response, err = await 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
)
```

{% endtab %}

{% tab title="Python: example" %}

```python
import time

tx_info, response, err = await 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=int(time.time() * 1000) + 365 * 24 * 3600 * 1000,  # 1 year from now, in ms
)
if err is not None:
    raise Exception(err)
```

{% endtab %}

{% tab title="TypeScript (WASM)" %}

```typescript
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.L1Sig
```

{% endtab %}
{% endtabs %}

You can find the full Python example [here](https://github.com/elliottech/lighter-python/blob/main/examples/integrator/approve.py). The TypeScript example uses the WASM signer from the [TypeScript quickstart](/developers/getting-started/quickstart-typescript.md); see [When an L1 signature is required](/developers/reference/wasm-signer.md#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](https://docs.lighter.xyz/api/system) 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:

```python
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 trades
```

These fees **must not exceed the maximum values** defined during the approval step. The same fields exist on modify and grouped orders.

{% hint style="warning" %}
**Non-zero partner fees can't be combined with custom self-trade prevention**

If an order sets a non-zero `integratorTakerFee` or `integratorMakerFee` together with any self-trade mode other than the default (`0, 0`: expire maker, same account index), it is rejected with `21159` "self-trade specifications are not allowed when there are non-zero fees". Zero-fee attribution (tracking only) works with any self-trade mode.
{% endhint %}

### Example: Creating an Order

{% tabs %}
{% tab title="Python" %}

```python
tx, response, err = await 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,
)
```

{% endtab %}

{% tab title="TypeScript (WASM)" %}

```typescript
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,
);
```

{% endtab %}
{% endtabs %}

You can find the full Python example [here](https://github.com/elliottech/lighter-python/blob/main/examples/integrator/create_modify_order.py).

## 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](https://docs.lighter.xyz/api/info).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.lighter.xyz/developers/integration-guides/partner-attribution.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
