Scenario
A user holds 1,000 USDT on Ethereum and wants Aave USDC (aEthUSDC). No single routing edge turns USDT into aEthUSDC, so the route takes two hops: swap USDT to USDC, then deposit the USDC into Aave.
sdk.route (POST /compose/route) plans those hops for you. You pass the token pair, an amount and a signer; the server builds the route, compiles it and returns the same ComposeCompileResult as builder.compile(). It plans up to two hops on one chain, and a lifi.swap can only be the first hop. The other hops are lifi.zap catalog edges: a protocol deposit or withdrawal, a wrap or unwrap. For a longer route, a route you choose yourself, or guards on intermediate outputs, author a Flow as in Swap and deposit.
Full example
Install the SDK and viem withnpm install @lifi/composer-sdk @lifi/compose-spec viem and set LIFI_API_KEY; see Before you start. The example also signs with a private key: set PRIVATE_KEY on your server and never ship it to a browser.
Run it
Save the file asserver-planned-route.mts and run node server-planned-route.mts.
What to check
- The node ids follow a fixed pattern:
hop0,hop1, … and a last node namedzap. The server does not return the Flow it built. outputs['hop0.amountOut']is the swap’s USDC, withrole: 'consumed'andconsumedBy: 'zap'. Its floor comes from the swap quote.outputs['zap.amountOut']is the aEthUSDC the signer receives:role: 'terminal',delivery: { when: 'now' }.amount.estimateis simulated;amount.minimum(basis: 'guard') is 1% below it. Read this key at any route length.epilogue.remainderis thesweepToaddress, which receives any leftover USDT or USDC.- The
executetransaction is atomic: if the aEthUSDC would fall below the floor, it reverts and the USDT stays with the signer.
Request fields
The SDK serialisesbigint amounts to decimal strings on the wire. sdk.route(request) lists the TypeScript types.
To check which pairs the catalog connects before calling the server, pass
await sdk.client.getZapPacks() to buildReachability. It does not report swap-headed routes, so USDT to aEthUSDC shows as unreachable there; see the SDK reference.
Errors
no_route_error(HTTP 404, SDK codeNOT_FOUND): no route within the hop limit. The details carrymaxHopsandsearchTruncated. A plain token-to-token swap, such as USDC to UNI, fails this way: uselifi.swap.validation_error(HTTP 400) “sweepTo is required”: the pair needs a swap and the request has nosweepTo.
Related
- Swap and deposit: the same deposit with steps you pick.
lifi.zap: the catalog edges a route can use.

