Skip to main content
Gasless execution lets a user swap or bridge without holding the source chain’s native token. Instead of sending a transaction, the user signs an EIP-712 payload. LI.FI relays that payload on-chain and pays the gas, then charges the relay cost as a fee in the input token and itemizes it in the quote. This guide covers only what gasless adds on top of a standard integration. For the concepts it builds on, see requesting routes and quotes, quote versus route, status tracking, and the API reference for authentication and rate limits.

How it works

Get a signable step

Add gasless=true to a standard quote request, or set options.gasless: true on a routes request and post the chosen step for transaction data. Either path returns a step carrying an EIP-712 payload, an expiry, and a relay-fee entry in the cost estimate.

Sign

The user signs the typed data with eth_signTypedData_v4. No transaction leaves the user’s account and no native token is required.

Relay

Post the signed step to POST /v1/advanced/relay. LI.FI verifies the signature, validates the payload against the original quote, and broadcasts from a relayer account. The response carries a task ID.

Track

Poll GET /v1/status?taskId=... until the transfer reaches DONE or FAILED.
The signed payload is a batch of calls executed through the user’s own account under EIP-7702 delegation: the relay fee transfer, a token approval for ERC-20 input, and the swap or bridge call. The relayer can only submit the batch exactly as signed, and the batch executes all or nothing. If any call reverts, everything reverts, including the fee transfer.

Requirements

An undelegated EOA can’t currently be served. /v1/quote can return a generic no-quote error for this case. To retrieve the specific account-and-chain reason, request routes and inspect unavailableRoutes.filteredOut[].reason.

Step 1: Get a signable step

Both standard quoting flows work unchanged. Gasless is a request flag. Add gasless=true to a standard quote request, and the response is the signable step:
To pick from several routes instead, request routes with options.gasless: true in the standard /v1/advanced/routes body. Those routes already price in the relay fee but don’t yet carry the signable payload. Post the chosen route’s step, unmodified, to /v1/advanced/stepTransaction, and the response comes back in the same shape as the single-call quote.
Gasless isn’t available on /v1/quote/toAmount or combined with executionType=message or executionType=all; those requests are rejected. /v1/quote/contractCalls does not support gasless execution and ignores the gasless field, so the request proceeds as a normal contract-call quote. Reverse quoting is rejected because its convergence loop only solves for percentage-based fees and can’t solve for a flat, gas-denominated relay fee.

The signable step

A gasless step is a standard LI.FI step with two extra properties, plus the relay-fee entry in the cost estimate:
  • typedData is ready for eth_signTypedData_v4. Under EIP-7702 delegation the account executing the batch is the user’s own address, which is why domain.verifyingContract is that address. The delegate implementation is bound through domain.salt.
  • expiresAt is Unix seconds and equals the payload’s deadline. The validity window is short, in minutes rather than hours. After expiry, request a fresh quote. Nothing is charged.
  • transactionRequest isn’t used here. Execution happens through the signed typed data and the relay endpoint.
Submit the step to the relay exactly as received. LI.FI verifies it against a record stored at quote time, so any change to the calls, amounts, recipient, or deadline is rejected.

Step 2: Sign the payload

Sign with standard EIP-712 typed-data signing. When passing the payload to a wallet over JSON-RPC, use it exactly as returned, because the types object includes the EIP712Domain entry that wallets validate.

Step 3: Submit the relay

Post the step exactly as received, with the signature added to the typed-data entry:
TypeScript
On acceptance the endpoint responds 200:
Acceptance means LI.FI has verified the signed execution, recorded it durably, and the downstream executor accepted it for submission. Persist the returned task ID and use the status endpoint after acceptance. If the request fails before that acknowledgement, treat the outcome as ambiguous and follow the retry guidance below rather than assuming the payload was or was not accepted.

Relay errors

Rejections use the standard LI.FI error response: the same body shape, the same numeric error codes, and the same HTTP statuses as every other endpoint. The status and code identify the resolution. The message explains which check failed, for your logs and for support. Failures reported before downstream submission do not broadcast a transaction or charge the user. A 424 is different: it can represent an ambiguous downstream outcome and must not be treated as proof that nothing was submitted.

Step 4: Track the execution

Status tracking works as described in the status tracking guide, with two gasless specifics. The execution is addressable by task ID from the moment the relay is accepted, before any transaction exists. Once a transaction hash appears in the response, the same execution also resolves by hash.
curl
Two states are specific to gasless: Everything else follows the standard status semantics. The response attributes the transfer to the signing user’s address rather than the relayer, so your accounting behaves the same as it does for self-submitted transactions.

Fees

The relay fee covers the gas LI.FI spends executing on the user’s behalf. It’s a flat, gas-denominated amount derived from the chain’s gas profile and the live gas price at quote time, then converted into the input token. The same value appears at /v1/quote, /v1/advanced/routes, and /v1/advanced/stepTransaction. It arrives in the cost estimate under the stable name LIFI Gasless Relay Fee with included: true, which means it’s deducted from fromAmount before routing and the quoted output already reflects it. The user’s total spend is exactly fromAmount. On-chain, the fee transfer is the first call of the signed batch. The signature covers it, so the relayer can’t alter it, and it’s atomic with the swap, so it can’t be collected unless the swap executes. Rejected relays, expired signatures, and failed executions charge nothing.
The fee is fixed in the signed quote, but relay-time checks still reject it with 409 if gas prices move beyond the accepted tolerance. Request a fresh quote when that happens.

When gasless can’t be served

On /v1/quote, a refusal comes back as the standard not-found error. On /v1/advanced/routes it appears in unavailableRoutes.filteredOut, where reason is a human-readable sentence explaining the specific refusal, following the same convention as every other route filter. Show it to the user or write it to your logs. Don’t match on it programmatically. Gasless requests are refused when:
  • the account is an undelegated EOA, or delegates to a contract LI.FI doesn’t relay for;
  • the account is a smart contract wallet;
  • the request carried no fromAddress;
  • the route charges a fixed native-token fee on top of the input amount, which a gasless user can’t fund. Other tools may still serve the same trade;
  • the relay fee would not leave enough of the input amount behind, which is what puts a floor under trade size.

Operational notes

Distinct quotes use independent keyed nonces and can coexist for the same account. A 409 nonce conflict means the nonce for that signed quote no longer matches on-chain state, for example because the same execution was already consumed. Request a fresh quote rather than re-signing or modifying the old payload.
The signature deadline is short. Request the quote when the user is ready to sign, and relay straight after signing. Stale-fee and expired-quote rejections are routine, and neither costs anything, so refresh and retry.
Every quote embeds account state and a short deadline. Treat it as an ephemeral signing artifact, honor expiresAt, and request it only when the user is ready to sign.
After a timeout or 424, retry only the exact signed request with backoff; never create a replacement execution immediately. A retry can resume an existing pre-broadcast record, return 404 when quote integrity was consumed before acceptance, or return 409 after nonce or fee state changed. Re-quote after 404; after 409, first reconcile whether the original execution advanced. After a successful acknowledgement, persist the task ID and track status instead of replaying the payload.

Next steps

Gas Fronting

Deliver native gas alongside a bridged asset so users can transact on arrival.

Status tracking

The full status and substatus vocabulary for a transfer.

Error codes

Every numeric code the API returns and what it means.

API reference

Authentication, rate limits, and the full endpoint surface.