Skip to main content
Get started with the Value Transfer API in minutes. This guide walks you through the complete transfer flow.

Prerequisites

  • An API key from LayerZero
  • A funded wallet on the source chain

Base URL

https://transfer.layerzero-api.com/v1

1

Check chains and tokens

Before requesting a quote, verify your source and destination chains are supported and discover available tokens.

List supported chains

curl -X GET "https://transfer.layerzero-api.com/v1/chains"

Response

FieldDescription
chainKeyUnique chain identifier (e.g., ethereum, base)
chainTypeBlockchain type (EVM, SOLANA, STARKNET)
chainIdNative chain ID (e.g., 1 for Ethereum, 8453 for Base)
See the Chains API reference for complete endpoint documentation.

List supported tokens

Query tokens with optional filters. Without parameters, the API returns all tokens across all supported chains.
# Get all tokens (full catalog)
curl -X GET "https://transfer.layerzero-api.com/v1/tokens"

# Get valid destinations for ETH from Base
curl -X GET "https://transfer.layerzero-api.com/v1/tokens?transferrableFromChainKey=&transferrableFromTokenAddress=&pagination%5BnextToken%5D="

Query parameters

ParameterTypeDescription
transferrableFromChainKeystringSource chain key (e.g., base, ethereum). Must be combined with transferrableFromTokenAddress to filter results.
transferrableFromTokenAddressstringSource token address. Must be combined with transferrableFromChainKey to filter results.
Valid destinations: To get all destination tokens you can transfer to, provide both the source chain and token address. See Tokens for the full endpoint reference.

Response

FieldDescription
isSupportedWhether the token is available for transfers
chainKeyChain identifier (e.g., ethereum, base)
addressToken contract address
decimalsToken decimal places
symbolToken symbol (e.g., ETH, USDC)
nameFull token name
price.usdCurrent price in USD
2

Get a quote

Request a quote for your cross-chain transfer. The API returns available routes with fees, estimated duration, and the steps needed to execute.
Quote response: The quote includes userSteps with transaction or signature data to execute. See Quotes for the full request/response schema.
curl -X POST "https://transfer.layerzero-api.com/v1/quotes" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "srcChainKey": "base",
    "dstChainKey": "optimism",
    "srcTokenAddress": "<0xTOKEN_ADDRESS>",
    "dstTokenAddress": "<0xTOKEN_ADDRESS>",
    "srcWalletAddress": "<0xYOUR_WALLET>",
    "dstWalletAddress": "<0xYOUR_WALLET>",
    "amount": "<AMOUNT_IN_LOCAL_DECIMALS>",
    "options": {
      "amountType": "EXACT_SRC_AMOUNT",
      "feeTolerance": { "type": "PERCENT", "amount": 2 }
    }
  }'
3

Build user steps (Solana only)

For EVM transfers, the quote response already includes userSteps with transaction data - skip to Step 4.For Solana transfers, you must call /build-user-steps to get the encoded transaction data. Solana transactions have short blockhash validity (~60 seconds), so this step generates fresh transaction data.
EVM vs Solana:
Chain typeWhere to get userSteps
EVMDirectly from the quote response
SolanaMust call /build-user-steps first
See Build User Steps for complete documentation.
curl -X POST "https://transfer.layerzero-api.com/v1/build-user-steps" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"quoteId": "QUOTE_ID"}'
4

Execute the transfer

Process each user step in order. For transactions, sign and submit to the blockchain. For signatures, sign and submit to the API.
Never approve the LZMulticall (Wrapper) as a token spenderLZMulticall executes bridge transactions. It is not the right spender, and approving it will lose you tokens. The correct spender is the TransferDelegate, and the API’s approve step already has this set in the calldata. Execute every userStep as returned.See Contracts Overview for details on the contract architecture.
No cURL for execution: Executing requires a wallet to sign and broadcast the transaction. This step cannot be done with cURL alone - you need a signing library (viem, web3.py, @solana/web3.js) and an RPC connection.
Where to get userSteps:
  • EVM: Use quote.userSteps directly from the quote response
  • Solana: Use userSteps from the /build-user-steps response

Execute transaction steps

Loop through every userStep and execute each one in order. ERC20 transfers return two transaction steps (approve + bridge) — you must execute both.
import {createWalletClient, createPublicClient, http} from 'viem';
import {privateKeyToAccount} from 'viem/accounts';
import {base} from 'viem/chains';

const account = privateKeyToAccount('0xYOUR_PRIVATE_KEY');
const wallet = createWalletClient({account, chain: base, transport: http()});
const client = createPublicClient({chain: base, transport: http()});

let txHash;

for (const step of userSteps) {
  if (step.type !== 'TRANSACTION') continue;

  const tx = step.transaction.encoded;
  txHash = await wallet.sendTransaction({
    to: tx.to,
    data: tx.data,
    value: BigInt(tx.value ?? '0'),
  });

  // Wait for confirmation before executing the next step
  await client.waitForTransactionReceipt({hash: txHash});
  console.log(`${step.description} tx confirmed:`, txHash);
}

Submit a signature step

For intent-based routes, sign the EIP-712 data and submit to the API.
Signature steps: See Submit Signature for EIP-712 typed data handling and BigInt conversion requirements.
// Sign the typed data from userStep.signature.typedData
const typed = userStep.signature.typedData;

const signature = await wallet.signTypedData({
  domain: typed.domain,
  types: typed.types,
  primaryType: typed.primaryType,
  message: typed.message,
});

// Submit to API
await fetch('https://transfer.layerzero-api.com/v1/submit-signature', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    quoteId: quote.id,
    signatures: [signature],
  }),
});
5

Track the transfer

After executing all user steps, poll the status endpoint to monitor completion.
Polling: Poll every 4 seconds until status is SUCCEEDED or FAILED. See Status for response details and error handling.
curl -X GET "https://transfer.layerzero-api.com/v1/status/QUOTE_ID?txHash=0xYOUR_TX_HASH" \
  -H "x-api-key: YOUR_API_KEY"

Status values

StatusDescription
PENDINGTransfer initiated, waiting for confirmation
PROCESSINGTransfer in progress across chains
SUCCEEDEDTransfer completed successfully
FAILEDTransfer failed
UNKNOWNStatus cannot be determined

Next steps