Account Types

Lighter API users can operate under a Standard or Premium account.

Premium Account (Opt-in) -- Suitable for HFT, the lowest latency on Lighter. Part of volume quota program.

Latency for maker & cancel orders is 0ms.

Staked LITMaker/Taker Fee DiscountMaker FeeTaker FeeTaker LatencyLatency Improvement
00.0040%0.0280%200 ms
1,0002.5%0.0039%0.0273%195 ms2.5%
3,0005%0.0038%0.0266%190 ms5%
10,00010%0.0036%0.0252%180 ms10%
30,00015%0.0034%0.0238%170 ms15%
100,00020%0.0032%0.0224%160 ms20%
300,00025%0.0030%0.0210%150 ms25%
500,00030%0.0028%0.0196%140 ms30%

Standard Account (Default) -- Suitable for retail and latency-insensitive traders.

Maker FeeTaker FeeTaker LatencyMaker/Cancel Latency
0%0%300 ms200 ms

Account Switch

You can change your Account Type (tied to your L1 address) using the /changeAccountTier endpoint.

You may call that endpoint if:

  • You have no open positions
  • You have no open orders
  • At least 24 hours have passed since the last call

Python snippet to switch tiers:

import asyncio
import logging
import lighter
import requests

logging.basicConfig(level=logging.DEBUG)

BASE_URL = "https://mainnet.zklighter.elliot.ai"

# You can get the values from the system_setup.py script
# API_KEY_PRIVATE_KEY =
# ACCOUNT_INDEX =
# API_KEY_INDEX =


async def main():
    client = lighter.SignerClient(
        url=BASE_URL,
        private_key=API_KEY_PRIVATE_KEY,
        account_index=ACCOUNT_INDEX,
        api_key_index=API_KEY_INDEX,
    )

    err = client.check_client()
    if err is not None:
        print(f"CheckClient error: {err}")
        return

    auth, err = client.create_auth_token_with_expiry(
        lighter.SignerClient.DEFAULT_10_MIN_AUTH_EXPIRY
    )

    response = requests.post(
        f"{BASE_URL}/api/v1/changeAccountTier",
        data={"account_index": ACCOUNT_INDEX, "new_tier": "premium"},
        headers={"Authorization": auth},
    )
    if response.status_code != 200:
        print(f"Error: {response.text}")
        return
    print(response.json())


if __name__ == "__main__":
    asyncio.run(main())
import asyncio
import logging
import lighter
import requests

logging.basicConfig(level=logging.DEBUG)

BASE_URL = "https://mainnet.zklighter.elliot.ai"

# You can get the values from the system_setup.py script
# API_KEY_PRIVATE_KEY =
# ACCOUNT_INDEX =
# API_KEY_INDEX =


async def main():
    client = lighter.SignerClient(
        url=BASE_URL,
        private_key=API_KEY_PRIVATE_KEY,
        account_index=ACCOUNT_INDEX,
        api_key_index=API_KEY_INDEX,
    )

    err = client.check_client()
    if err is not None:
        print(f"CheckClient error: {err}")
        return

    auth, err = client.create_auth_token_with_expiry(
        lighter.SignerClient.DEFAULT_10_MIN_AUTH_EXPIRY
    )

    response = requests.post(
        f"{BASE_URL}/api/v1/changeAccountTier",
        data={"account_index": ACCOUNT_INDEX, "new_tier": "standard"},
        headers={"Authorization": auth},
    )
    if response.status_code != 200:
        print(f"Error: {response.text}")
        return
    print(response.json())


if __name__ == "__main__":
    asyncio.run(main())

How fees are collected:

In isolated margin, fees are taken from the isolated position itself, but if needed, we automatically transfer from cross margin to keep the position healthy. In cross margin, fees are always deducted directly from the available cross balance.

Sub-accounts share the same tier as the main L1 address on the account.