gasCosts and feeCosts. They answer different questions, they are denominated differently, and neither one maps cleanly onto “what the user pays on each chain”. This guide explains how to read both so you can show your users an accurate cost breakdown.
Where the cost arrays live
Both arrays hang off anestimate object, and estimate belongs to a step. Not every response hands you a step directly.
A route is an envelope around its steps and has no
estimate of its own. Reading route.estimate gives you undefined. The only cost figure a route carries at the top level is gasCostUSD, a single aggregate string.
Both arrays are optional. A step can come back with neither, or with an empty array, and that is a valid quote rather than a quoting failure. Guard every read before you index into one.
gasCosts or feeCosts?
The split is about who submits a transaction, not about what the money is for.
A cost being for gas does not put it in
gasCosts. A bridge that pays for destination-chain execution and bills the user for it reports that as a feeCosts entry, because the user never signs a destination transaction.
Reading a gas cost
price is in the smallest unit of the gas token per unit of gas, so wei per gas on EVM chains, not gwei. For EVM entries, amount is estimate * price, and limit is estimate plus a buffer. Other ecosystems may apply chain-specific units and rounding, so treat the returned amount as authoritative rather than reconstructing it. When constructing an EVM transaction from these fields, use limit, not estimate.
Gas cost types
GasCost.type is typed as one of four values, but only one of them is in production use.
Handle
APPROVE, FEE, and SUM if they appear, so your integration stays forward-compatible, but don’t build a flow that depends on them. If you need the gas cost of an approval today, estimate it yourself against approvalAddress.Which chain does a cost belong to?
token.chainId tells you the chain of the token a cost is denominated in. It does not tell you where the underlying work happens.
For gasCosts the two coincide: gas is paid in the native token of the chain that consumes it, so token.chainId is the execution chain.
For feeCosts they often differ. In this quote, 50 USDC on Ethereum is sent to cbBTC on Base:
chainId: 1 as “this is a source-chain cost” is the mistake to avoid.
Where destination execution cost shows up
LI.FI does not guarantee a separate source-chain and destination-chain gas item. Depending on the tool, the cost of executing on the destination chain reaches you in one of three ways:- As a
feeCostsentry, typically named something likeRelayer Gas feeorNetwork fee, denominated in the source-chain token. This is the most common case. - As tool-specific data, for example a
destinationGasConsumptionvalue insideestimate.data. The shape varies by tool. - Priced into the output, with no separate line item. The quoted
toAmountis already net of it.
Relayer Gas fee, Relayer gas fee, and Network fee all exist across different tools. Display name and description to users, but never branch on them.
Does the user need native gas?
The answer depends on who broadcasts the source transaction, so start from the execution mode you integrated.
Destination-chain native gas is normally not needed in either mode. LI.FI or the bridge executes on the destination side, and any cost reaches you through
feeCosts or is priced into toAmount.
Gasless availability is determined at quote time. It currently requires an EVM source chain and an EIP-7702 delegated account that LI.FI supports; not every chain, delegate, or account type is eligible. See Gasless Transactions for the current requirements and execution flow.
If your integration self-submits, check the native balance on the source chain against gasCosts[].amount before letting a user sign. A user with enough USDC but no ETH will fail at submission, not at quoting. If you relay, that check does not apply to the user, and a gasCosts entry describes what the relayer spends rather than what the user must hold.
See Permit and Permit2 Approval Flow for the signature the legacy relayed path expects.
The destination case has one exception worth planning for: your user lands on a new chain with the bridged token and no native balance, so they can’t do anything next. That is a cold-start problem, not an execution problem, and LI.Fuel solves it.
LI.Fuel is not execution gas
fromAmountForGas converts part of the sent amount into the destination chain’s native token and delivers it to the user alongside the bridged asset. It exists so the user has gas for their next action.
Keep the two separate when you build a cost breakdown:
- Execution gas is what it costs to complete this transfer. It shows up in
gasCostsandfeeCosts. - LI.Fuel is an extra amount the user asked to receive as native token. It reduces
toAmount, and it is not a cost of the transfer.
The included flag
included decides whether a fee is already reflected in the quoted amounts.
included: truemeans the fee is already accounted for. The quotedtoAmountis net of it. Show it in a breakdown, but do not add it again as a separate user payment.included: falsemeans the user pays it on top offromAmount.
included: true fee back on top is the most common way integrations end up overstating cost to their users.
Don’t add the top-level and step-level arrays together
Alifi step carries its own estimate.feeCosts and estimate.gasCosts, and each entry in includedSteps carries its own. The top-level arrays are derived from the step-level ones, so summing both double counts.
They are derived differently, which matters:
feeCostsat the top level is the concatenation of every included step’s fee costs. Same entries, same amounts.gasCostsat the top level is a single estimate for the transaction that is actually submitted. It aggregates raw gas costs from included steps on the source chain and, for EVM transactions, adds estimated LI.FI contract overhead. It may therefore differ from—and often exceed—the sum of the source-chain per-step entries. Raw gas costs from destination-chain included steps are not added directly.
In this example the fee columns match and the gas columns do not, because the top-level figure covers the single transaction the user actually submits, including LI.FI contract overhead.
Next Steps
Gas Fronting
Deliver destination-chain native token to your users with
fromAmountForGas.Fees and monetization
How integrator fees are configured and collected.
Quote API reference
The full response shape, including
estimate, feeCosts, and gasCosts.Route and quote differences
When to call
/quote and when to call /advanced/routes.
