Skip to content
Swap history

LCX Liberty. American DeFi. Your keys. Your assets. Your control.

API reference

Swap history

GET /v1/swaps returns every swap an address made through our routers, on every chain, newest first.

Request

GET/v1/swaps

Served from our own index, not from the chain: no node call happens on the request path, so history reaches back further than any single eth_getLogs window would allow. A swap is identified by the transaction it was made in, one whose to is one of our routers, so the record covers routers that emit no event at all, including the superseded core proxy and the cross-chain router.

Query
address*string

The wallet whose history you want.

chainIdnumber

One chain. Omit it and every chain is merged into one timeline.

limitnumber

1–100, default 25. Out-of-range values are clamped, not rejected.

cursorstring

The nextCursor from the previous page. See Paging.

* required

What a row carries

json
{
  "chainId": 1,
  "txHash": "0x7b37e0fe…83ac",
  "blockNumber": 25796058,
  "blockTime": 1787225639,
  "txIndex": 176,
  "logIndex": 735,
  "user": "0x899c9031…3cc9",
  "tokenIn": "0x0000000000000000000000000000000000000000",
  "tokenOut": "0xa0b86991…eb48",
  "amountIn": "10000000000000000",
  "amountOut": "23075528",
  "feeAmount": "0",
  "integrator": null,
  "router": "0x00000000…56F0",
  "routerKind": "fee",
  "method": "swapSplitWithPropAMMSplit",
  "selector": "0x31ab353b",
  "source": "event",
  "status": "success",
  "gasUsed": 301501,
  "toChainId": null,
  "bridgeTransferId": null
}

Amounts are base units as strings, never numbers: an amountIn of 1018 does not survive a JSON float. blockTime is Unix seconds, which is what makes a merged multi-chain list sortable at all; block numbers are not comparable across chains.

source says how the row was recognised. event means the router emitted LibertyRouted and the amounts are the contract's own word. transfer means they were reconstructed from the receipt's ERC-20 transfer legs, which is how swaps through routers that emit nothing are still recorded. routerKind distinguishes those routers.

status can be reverted. A reverted router call is a real transaction and belongs in a history, but it moved nothing; its amountOut is zero. Filter it out before summing volume, and never render it as a completed trade.

toChainId is non-null only when the output was delivered on a different network, and bridgeTransferId then links the row to /v1/bridge/transfers/{id}. On a same-chain swap both are null.

Coverage: how far back the answer goes

Every response carries a coverage array, one entry per chain, and it is the difference between “you made no swaps” and “we have not walked that far”. An empty list without reading it is not an answer.

json
"coverage": [
  { "chainId": 1, "complete": true,
    "fromBlock": 25626182, "fromTime": 1785179843,
    "toBlock": 25874066,  "toTime": 1788164867,
    "targetFromBlock": 25626182 }
]

fromTime is the oldest moment we can speak for on that chain. complete is true once the walker has reached its targetFromBlock. If a chain is missing from coverage entirely, it has not been walked at all. Say so in your UI rather than implying the wallet was idle.

Paging

Keyset, not offset. Pass the previous page's nextCursor; a null nextCursor is the end of the list. The sort key is (blockTime, chainId, txHash, logIndex): block time, because with chainId omitted every chain is merged into one timeline and block numbers do not compare across chains.

bash
curl -s "https://swap-api.lcx.com/v1/swaps?address=0x…&limit=25" \
  -H "Authorization: Bearer $LCX_API_KEY"

# next page
curl -s "https://swap-api.lcx.com/v1/swaps?address=0x…&limit=25&cursor=1787212138:42161:0x…:1" \
  -H "Authorization: Bearer $LCX_API_KEY"

Walker health

GET/v1/swaps/health

Per-chain indexer state: head, frontier and coveredFrom block, mode (tip or backfill), backfillRemainingBlocks, reorgs, windowsOk / windowsFailed and the last error. Use it to explain a short history rather than guessing at one.

Both routes answer 503 swaps_unavailable where history is not enabled for the deployment, or its store is unreachable. That is a configuration state, not a failed request. The wallet is not empty, and a client should say so differently.