Cryptocurrency trading involves risk. Prices may be volatile. Trade responsibly. Read our security notes
For developers, trading desks and data providers

API Documentation

Public market data over REST and WebSocket, with no key and no account — plus how private trading access is issued.

API Overview

Lovely Legends exposes two surfaces. The public market data API is open — pairs, tickers, order book, trades and candles, over REST and WebSocket, with no credential of any kind. The private trading API covers order entry, cancellation, balances and account state, and is issued per account.

Public market data

Open to anyone, including data aggregators and listing platforms. It is the same feed the market board and chart on this website are built from, so what you receive is what our own users see.

WebSocket streaming

Depth, trades, tickers and candles push over one connection. Public channels need no token; private ones carry only the authenticated account's own activity.

Private trading API

Keys are issued per account with the secret shown once, requests are signed, and every key is pinned to the IP addresses you nominate — so a leaked secret is not on its own a usable credential.

Private trading API access is currently available only for approved partners and market makers. Endpoint-by-endpoint documentation for order entry and account state is sent directly with the keys. The public market data surface below is open to everyone and needs no application.

Public Market Data API

Base URL https://llapi.lflabs.fund. No key, no account, no sign-up. Every endpoint below was called unauthenticated against this host before it was documented.

EndpointParametersReturnsAuth
GET /exchange/pairsEvery listed market: base, quote, price/quantity/amount precision, trading schedule, listing price, contract address, deposit and withdrawal status.Public
GET /exchange/tickerpair24h statistics for one market: last price, open, change, high, low, base and quote volume, and trade count.Public
GET /exchange/orderbookpairAggregated resting depth — bids and asks as [price, quantity] pairs — plus the last print.Public
GET /exchange/market-tradespair, limitThe recent public trade tape: id, price, quantity, timestamp and side.Public
GET /exchange/candlespair, timeframe, from, to, limitOHLCV candles: open/close time, open, high, low, close, base and quote volume, trade count, and whether the bucket has closed.Public

pair is URL-encoded, e.g. LF%2FUSDT. Every endpoint defaults pair to LF/USDT, timeframe to 1h and the trade tape limit to 50. Candle limit is clamped server-side at 1000; page further back by passing to = the oldest candle you already hold.

Response Examples

Real responses from the endpoints above, trimmed for length. Figures move with the market; field names do not.

Market pairspublic · no credential
curl -s "https://llapi.lflabs.fund/exchange/pairs"
Responseshape — one object per listed market
[
  {
    "pair": "LF/USDT",
    "base": "LF",
    "quote": "USDT",
    "pricePrecision": 8,
    "quantityPrecision": 0,
    "amountPrecision": 2,
    "tradeStartAt": "2026-07-31T13:00:00.000Z",
    "tradingOpen": true,
    "listingPrice": null,
    "name": "LF Labs",
    "contractAddress": "0x957c7fa189a408e78543113412f6ae1a9b4022c4",
    "depositOpen": true,
    "withdrawOpen": true
  }
]
Tickerpublic · no credential
curl -s "https://llapi.lflabs.fund/exchange/ticker?pair=LF%2FUSDT"
Responseshape — figures vary with the market
{
  "pair": "LF/USDT",
  "lastPrice": "0.000048260000000000",
  "open24h":   "0.000051010000000000",
  "change24h": -5.3910997843560065,
  "high24h":   "0.000052000000000000",
  "low24h":    "0.000048210000000000",
  "volumeBase24h":  "818146654.414143316656356334",
  "volumeQuote24h": "41469.118874635982053838",
  "trades24h": 4615
}
Order bookpublic · no credential
curl -s "https://llapi.lflabs.fund/exchange/orderbook?pair=LF%2FUSDT"
Responseshape — [price, quantity], asks ascending, bids descending
{
  "asks": [
    ["0.000049",  "97935"],
    ["0.0000495", "102366"],
    ["0.00005",   "80000"]
  ],
  "bids": [
    ["0.00004826", "147949"],
    ["0.00004824", "322761"]
  ]
}
Recent tradespublic · no credential
curl -s "https://llapi.lflabs.fund/exchange/market-trades?pair=LF%2FUSDT&limit=2"
Responseshape — newest first, `ts` in seconds
[
  {
    "id": "17379",
    "price": "0.000048260000000000",
    "quantity": "147949.000000000000000000",
    "ts": 1785766630,
    "side": "buy"
  }
]
Candlespublic · no credential
curl -s "https://llapi.lflabs.fund/exchange/candles?pair=LF%2FUSDT&timeframe=1h&limit=2"
Responseshape — `filled: false` marks a bucket still open
{
  "pair": "LF/USDT",
  "timeframe": "1h",
  "candles": [
    {
      "openTime": 1785758400,
      "closeTime": 1785762000,
      "open":  "0.000050920000000000",
      "high":  "0.000052000000000000",
      "low":   "0.000049500000000000",
      "close": "0.000049910000000000",
      "volumeBase":  "38153574.414143316656356334",
      "volumeQuote": "1940.386991125982053838",
      "trades": 211,
      "filled": false
    }
  ]
}

Prices and sizes are strings, deliberately — they are exact decimals, and parsing them into a float is how a rounding error enters an order. Fields are null rather than zero when a market has not printed in the window, so "no data" and "zero" stay distinguishable.

WebSocket

One connection at wss://llapi.lflabs.fund/ws. Subscribe with {"op":"subscribe","channel":"…"}; the server answers with a subscribed ack and then pushes frames carrying a data field.

ChannelCarriesAuth
depth:<pair>Order book snapshots and updates.Public
trade:<pair>The public trade tape, as prints happen.Public
ticker:<pair>Rolling 24h statistics for the market.Public
kline:<pair>:<timeframe>Live candle updates for one timeframe.Public
fillsYour own fills as they execute.Token required
ordersYour own order state changes.Token required
Subscribe to public depthpublic · no token
const ws = new WebSocket("wss://llapi.lflabs.fund/ws")

ws.onopen = () => {
  ws.send(JSON.stringify({ op: "subscribe", channel: "depth:LF/USDT" }))
  ws.send(JSON.stringify({ op: "subscribe", channel: "trade:LF/USDT" }))
}
Frameswelcome, ack, then pushes
{"type":"welcome","channels":["depth:<pair>","trade:<pair>",
  "ticker:<pair>","kline:<pair>:<timeframe>","fills(auth)","orders(auth)"]}
{"type":"subscribed","channel":"depth:LF/USDT"}
{"channel":"depth:LF/USDT","data":{"asks":[…],"bids":[…]}}
Seed from the REST snapshot before applying pushes, and re-seed after a reconnect. A gap while a client was disconnected otherwise leaves stale levels resting in its book indefinitely — snapshots are absolute, deltas are not.

The private channels take a short-lived token from GET /exchange/ws-token, sent as {"op":"auth","token":"…"} after the connection opens. The token identifies the account server-side; a client cannot mint one for anybody else.

Rate Limits

SurfaceLimitNotes
Market data — ticker, order book, trades, candles120 requests / minutePer IP address, per endpoint. Comfortably above what a one-second poll needs on several markets.
Other public reads600 requests / minutePer IP address. Applies to the pairs registry and other unthrottled public routes.
WebSocketNo per-message limitStreaming is the intended way to follow a market continuously. Prefer one socket over repeated polling.
Private trading APIPer keySet per account and supplied with your keys. Market-making arrangements are configured case by case.
Exceeding a limit returns 429 rather than dropping the connection. Back off and retry; sustained abuse of the public surface may be blocked at the edge.

CoinGecko / Data Provider Integration

Lovely Legends provides public market data endpoints for exchange listing platforms, data aggregators and ecosystem partners: market pairs, ticker, order book, recent trades and candles. There is a dedicated reference for that audience — the Data Provider API page — with field semantics, example responses and rate limits in one place.

Lovely Legends is not currently listed on, approved by or partnered with any market data aggregator. These endpoints are open so that integration is possible, which is a different statement.

What is available today

All five REST endpoints and the four public WebSocket channels above, open and unauthenticated. Volumes and trade counts are reported from the matching engine's own settled trades, not from a separate statistics store.

Mapping to your schema

Field names follow the exchange's own model rather than any aggregator standard. If you need a specific response format — a particular ticker schema, a trades endpoint shaped a certain way — tell us which, and we will work through the mapping with you.

API Status

The system status page runs live reachability checks against these same public endpoints — REST and the WebSocket — from your own browser. Nothing on it is hand-edited, so it reports what your network can actually reach rather than what we would like it to say.

For integration help, a private API key, or a market-making arrangement, contact support@lflabs.fund or apply through the market maker programme. Treat anything not documented here as unreleased rather than undocumented.