Automation and agents
lifi is designed to be scriptable through --json.
Output conventions
The JSON shape depends on the command family:
- read commands like
vaults,inspect,recommend, andportfolioreturn the underlying API objects directly quote --jsonreturns the raw LI.FI quote object directlyquote --unsigned --jsonwraps the quote in an automation-friendly payloaddeposit --dry-run --jsonanddeposit --jsonreturn a staged execution payload withstage,status,message,quote, andpreflight- failures return a normalized error payload with
stage,status,message, andcode
This means the most automation-friendly write flows are:
lifi quote ... --unsigned --json
lifi deposit ... --dry-run --json
lifi deposit ... --wait --verify-position --jsonCommon patterns
List vaults for ranking:
lifi vaults --chain base --asset USDC --transactional-only --jsonPrepare a quote for downstream signing:
lifi quote \
--vault 0xVaultAddress \
--from-chain base \
--from-token USDC \
--amount 50 \
--unsigned \
--jsonThat JSON can also be fed back into:
lifi allowance --quote-file /path/to/quote.json --owner 0xYourWallet --jsonRun a safe preflight:
lifi deposit \
--vault 0xVaultAddress \
--from-chain base \
--from-token USDC \
--amount 50 \
--dry-run \
--jsonJSON examples
lifi vaults --json
This returns an array of Earn vault objects. The exact payload is the API object, so expect many more fields than shown here.
[
{
"id": "base:0xVaultAddress",
"slug": "csusdc-morpho-v1",
"name": "CSUSDC",
"address": "0xVaultAddress",
"chainId": 8453,
"network": "Base",
"isTransactional": true,
"isRedeemable": true,
"protocol": {
"name": "morpho-v1",
"url": "https://morpho.org"
},
"analytics": {
"apy": {
"total": 5.28,
"base": 4.91,
"reward": 0.37
},
"apy30d": 7.57,
"tvl": {
"usd": "4460216"
}
}
}
]lifi quote --json
This returns the raw LI.FI quote object directly.
{
"type": "lifi",
"id": "quote-id",
"tool": "stargate",
"action": {
"fromChainId": 10,
"toChainId": 8453,
"fromAmount": "50000000",
"fromAddress": "0xYourWallet",
"toAddress": "0xYourWallet",
"fromToken": {
"symbol": "USDC",
"address": "0x0b2c...",
"decimals": 6
},
"toToken": {
"symbol": "vault",
"address": "0xVaultAddress",
"decimals": 18
}
},
"estimate": {
"approvalAddress": "0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE",
"fromAmount": "50000000",
"toAmount": "49810234912830912",
"toAmountMin": "49561183738266752",
"executionDuration": 86,
"gasCosts": [
{
"amountUSD": "0.42",
"limit": "281000"
}
]
},
"transactionRequest": {
"from": "0xYourWallet",
"to": "0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE",
"data": "0x...",
"value": "0",
"chainId": 10,
"gasPrice": "120000",
"gasLimit": "281000"
},
"transactionId": "tx-id"
}lifi quote --unsigned --json
Use this when another system needs both the quote metadata and the unsigned transaction payload in one response.
{
"quote": {
"type": "lifi",
"id": "quote-id"
},
"unsigned_transaction": {
"from": "0xYourWallet",
"to": "0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE",
"data": "0x...",
"value": "0",
"chainId": 10,
"gasPrice": "120000",
"gasLimit": "281000"
},
"stage": "quote",
"status": "ok",
"message": "unsigned transaction prepared"
}lifi deposit --dry-run --json
This is the safest payload to key off for automation, because it includes the preflight checks and the quote in one place without broadcasting.
{
"stage": "dry-run",
"status": "ok",
"message": "deposit preflight completed",
"quote": {
"type": "lifi",
"id": "quote-id"
},
"preflight": {
"wallet_address": "0xYourWallet",
"source_chain": "Optimism (10)",
"source_token": "USDC",
"source_amount": "50",
"destination_vault": "0xVaultAddress",
"expected_received": "0.049810234912830912",
"approval_address": "0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE",
"approval_needed": true,
"approval_amount": "50",
"gas_policy": "auto",
"native_balance": "21340988106244091",
"native_balance_formatted": "0.021340988106244091",
"token_balance": "150000000",
"token_balance_formatted": "150",
"estimated_gas_wei": "476600000000000",
"estimated_gas_formatted": "0.0004766",
"quote_gas_limit": 281000,
"simulation_status": "skipped",
"simulation_message": "skipped until approval is granted"
}
}lifi deposit --wait --verify-position --json
After broadcast, the same result object is extended with transaction and verification fields.
{
"stage": "completed",
"status": "success",
"message": "deposit completed",
"tx_hash": "0xDepositTxHash",
"approval_tx_hash": "0xApprovalTxHash",
"receipt_status": 1,
"approval_receipt_status": 1,
"position_detected": true,
"status_payload": {
"status": "DONE",
"substatus": "COMPLETED"
},
"positions": [
{
"protocol": "morpho-v1",
"chain": "Optimism",
"asset": "USDC"
}
],
"quote": {
"type": "lifi",
"id": "quote-id"
},
"preflight": {
"wallet_address": "0xYourWallet",
"approval_needed": true,
"gas_policy": "auto"
},
"explorer_url": "https://optimistic.etherscan.io/tx/0xDepositTxHash"
}Error payload
Any command run with --json returns a normalized error object on failure:
{
"stage": "execution",
"status": "error",
"message": "insufficient balance: have 0 USDC, need 50 USDC",
"code": 14
}Exit code guide:
10: config error11: input error12: API error13: RPC error14: execution error15: verification error
Suggested automation contract
Expect these fields in machine output:
stagestatusmessagetx_hashapproval_tx_hashposition_detectedpreflightpreflight.simulation_statuspreflight.simulation_message
Practical recommendation:
- use
quote --unsigned --jsonwhen another signer or agent needs calldata - use
deposit --dry-run --jsonfor preflight gating - use
deposit --wait --verify-position --jsonfor end-to-end execution records - key off
stage,status, and exit code first, then inspect nested fields