LP API Integration Guide

A practical guide to building liquidity provisioning with the Uniswap API

Authentication

All requests require an API key:

curl -X POST https://api.uniswap.org/lp/create \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"protocol":"V4","walletAddress":"0x...","chainId":1,...}'

Basic create position request

const response = await fetch('https://api.uniswap.org/lp/create', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  body: JSON.stringify({
    walletAddress: '0x...',
    protocol: 'V3',
    chainId: 1,
    existingPool: {
      token0Address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
      token1Address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
      poolReference: '0x3470447f3cecffac709d3e783a307790b0208d60'
    },
    independentToken: {
      tokenAddress: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
      amount: '198251669183062942'
    },
    priceBounds: {
      minPrice: '0.000000000003248988534520805528430529',
      maxPrice: '0.000000000003936665827581813550758959'
    },
    simulateTransaction: false
  })
});

const result = await response.json();

Full code examples are available in LP Code Examples.

Architecture

Client-side responsibilities

The Uniswap API lp endpoints are a transaction-building service for liquidity provisioning operations. The API handles:

  • Pool State Fetching: Retrieves current reserves, ticks, sqrtRatioX96, and position data onchain
  • Dependent Amount Computation: Given one token amount, computes the required amount of the other token using the Uniswap SDK
  • Transaction Creation: Generates validated, fully-formed calldata for each LP action, ready for signature
  • Fee Computation: Derives uncollected fee amounts from the Data API for claim transactions
  • Gas Estimation: Optionally simulates transactions to provide gas fee estimates

Your application handles:

  • Transaction Broadcasting: Sign and submit transactions via your RPC provider
  • Gas Payment: Actual gas costs
  • Transaction Error Handling: Handle reverts and surface errors to users

See the Build Prerequisites for more details.

Required infrastructure

Your integration must include:

  • RPC Provider: Connection to blockchain nodes (e.g. Infura, Alchemy, or self-hosted)
  • Web3 Library: ethers.js, viem, or web3.js for transaction signing
  • Wallet Integration: Uniswap Wallet, MetaMask, or similar for user signing

Data flow

User Request (Create / Increase / Decrease / Claim)
    |
Your Application
    |-- Check & request token approvals (/lp/approve)
    |-- Get permit signature (if permitData returned) (Wallet)
    |-- Request LP transaction (/lp/create, /lp/increase, etc.)
    |-- Validate returned transaction payload
    |-- Get user signature for transaction (Wallet)
    +-- Broadcast transaction (via your RPC)
         |
    Blockchain

Available Endpoints

EndpointDescription
POST /lp/approveCheck token approvals and return approval transactions
POST /lp/createCreate a new Uniswap v3 or Uniswap v4 liquidity position
POST /lp/create_classicCreate a new Uniswap v2 liquidity position
POST /lp/increaseAdd liquidity to an existing Uniswap v2, v3, or v4 position
POST /lp/decreaseRemove liquidity from an existing Uniswap v2, v3, or v4 position
POST /lp/claimCollect accumulated fees from a Uniswap v3 or Uniswap v4 position

Protocol Versions

The LP API supports three Uniswap protocol versions. Pass the appropriate protocol field in each request:

ProtocolPositionsFee ClaimingFull-Range Only
V2✓ (via /create_classic)✗ (via LP token - /decrease)✓
V3✓ (via /create)✓ (via /claim)✗
V4✓ (via /create)✓ (via /claim)✗

Note: Uniswap v2 fees are embedded in LP token value and realized when liquidity is removed. Calling /lp/claim with protocol: "V2" returns a validation error.

Approval Flow

Before any LP transaction can be executed, tokens must be approved for spending. Always call /lp/approve first and execute any returned transactions before proceeding.

Check approvals

const approvalResponse = await fetch('https://api.uniswap.org/lp/approve', {
  method: 'POST',
  headers: {
    'x-api-key': API_KEY,
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  body: JSON.stringify({
    walletAddress: '0x...',
    protocol: 'V4',
    chainId: 1,
    lpTokens: [
      { tokenAddress: '0x...', amount: '1000000000000000000' },
      { tokenAddress: '0x...', amount: '500000000' }
    ],
    action: 'CREATE'
  })
});

const { approvals } = await approvalResponse.json();

Execute approval transactions

// approvals is a list of ApprovalTransactionRequest objects.
// If empty, all approvals are already in place — proceed to the LP action.
for (const approval of approvals) {
  validateTransaction(approval);
  const signedTx = await wallet.signTransaction(approval);
  await provider.sendTransaction(signedTx);
}

Permit-based approvals (Uniswap v4)

For Uniswap v4 positions, /lp/approve may return permitData (a BatchPermitData object) instead of an onchain transaction, enabling a gasless EIP-2612 approval flow.

let permitSignature: string | undefined;

if (permitData) {
  permitSignature = await wallet._signTypedData(
    permitData.domain,
    permitData.types,
    permitData.values
  );
}

// Pass the signature into the subsequent /lp/create or /lp/increase call:
const createBody = {
  ...positionParams,
  batchPermitData: permitData,
  signature: permitSignature
};

If generatePermitAsTransaction: true is passed to /lp/approve, permit data is returned as a standard executable transaction instead of typed data.

Uniswap v3 NFT permit

For Uniswap v3 positions, /lp/approve may return NFT permit data for the NonfungiblePositionManager. Sign and pass it through in the same pattern as Uniswap v4 permit data above.

Approval key parameters

ParameterDescription
protocolV2, V3, or V4
chainIdThe blockchain network
lpTokensArray of { tokenAddress, amount } objects
actionCREATE, INCREASE, DECREASE, or MIGRATE
generatePermitAsTransactionIf true, returns permit as a transaction instead of typed data

Creating a Position

Uniswap v3 and Uniswap v4 — /lp/create

The caller specifies a price range and the amount of one token. The API computes the corresponding amount of the second token based on current pool state.

Pool specification

Provide exactly one of:

  • existingPool — For an existing pool. Includes token0address, token1address, and poolReference (pool address for Uniswap v3, pool ID for Uniswap v4). The API fetches live pool state to compute the dependent token amount.
  • newPool — For initializing a new pool. Includes token addresses, fee, tickSpacing, optional hooks (Uniswap v4 only), and initialPrice as a sqrtRatioX96 string. The API uses the initial price to compute the dependent amount.

Price range

Provide exactly one of:

  • priceBounds — Human-readable decimal price strings (minPrice, maxPrice). The API converts to ticks, snaps to valid tick spacing, and returns the adjusted prices in the response.
  • tickBounds — Raw tick integers (tickLower, tickUpper). Skips price conversion. The API computes the corresponding decimal prices for the response.

Example request

curl --location 'https://api.uniswap.org/lp/create' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-api-key: XXXXX' \
--data '{
    "walletAddress": "XXXX",
    "existingPool": {
        "token0Address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
        "token1Address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
        "poolReference": "0x3470447f3cecffac709d3e783a307790b0208d60"
    },
    "chainId": 1,
    "protocol": "V3",
    "independentToken": {
        "tokenAddress": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
        "amount": "198251669183062942"
    },
    "priceBounds": {
        "minPrice": "0.000000000003248988534520805528430529",
        "maxPrice": "0.000000000003936665827581813550758959"
    },
    "simulateTransaction": false
}'

Response

interface CreatePositionResponse {
  token0: TokenAmount;
  token1: TokenAmount;
  tickLower: number;
  tickUpper: number;
  minPrice: string;
  maxPrice: string;
  create: TransactionRequest;
  gasFeeEstimates?: GasFeeEstimates; // present when simulateTransaction: true
}

Uniswap v2 — /lp/create_classic

Uniswap v2 positions always span the full price range (0 to ∞). The caller provides an independentToken amount; the API computes the dependentToken amount from current pair reserves. If creating a new pool, the independentToken and dependentToken fields are both required.

curl --location 'https://api.uniswap.org/lp/create_classic' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-api-key: XXXXX' \
--data '{
    "walletAddress": "XXXX",
    "poolParameters": {
        "token0Address": "0xc02fe7317d4eb8753a02c35fe019786854a92001",
        "token1Address": "0x0000000000000000000000000000000000000000",
        "chainId": 130
    },
    "independentToken": {
        "tokenAddress": "0xc02fe7317d4eb8753a02c35fe019786854a92001",
        "amount": "1000000000000000"
    },
    "dependentToken": {
        "tokenAddress": "0x0000000000000000000000000000000000000000",
        "amount": "1227700073369630"
    },
    "simulateTransaction": false
}'

If dependentToken is omitted, the API computes the optimal amount from current pool reserves.

Increasing Liquidity — /lp/increase

Adds liquidity to an existing Uniswap v2, v3, or v4 position. Provide one token amount; the API computes the other.

curl --location 'https://api.uniswap.org/lp/increase' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-api-key: XXXXX' \
--data '{
    "walletAddress": "XXXX",
    "chainId": 130,
    "protocol": "V4",
    "token0Address": "0x0000000000000000000000000000000000000000",
    "token1Address": "0x078D782b760474a361dDA0AF3839290b0EF57AD6",
    "nftTokenId": "1833079",
    "independentToken": {
        "tokenAddress": "0x078D782b760474a361dDA0AF3839290b0EF57AD6",
        "amount": "8223"
    },
    "simulateTransaction": false
}'

Native ETH: Use 0x0000000000000000000000000000000000000000 for native ETH token addresses. The API will generate a multicall that includes refundETH to return any excess ETH to the caller.

For Uniswap v4 permit-based approvals, include v4BatchPermitData and signature from the approval flow.

Key parameters

ParameterDescription
protocolV2, V3, or V4
chainTdThe blockchain network
token0Address / token_1_addressThe token pair addresses
nftTokenIdRequired for Uniswap v3 and Uniswap v4. NFT token ID identifying the position.
independentTokenToken address and amount the user wants to add
slippageToleranceOptional. Decimal slippage tolerance (e.g., 0.5 for 0.5%)

Decreasing Liquidity — /lp/decrease

Removes a percentage of liquidity from a Uniswap v2, v3, or v4 position. The API computes the token amounts to be returned and generates the withdrawal transaction.

curl --location 'https://api.uniswap.org/lp/decrease' \
--header 'Content-Type: application/json' \
--header 'x-api-key: XXXXX' \
--data '{
    "walletAddress": "XXXX",
    "chainId": 130,
    "protocol": "V4",
    "token0Address": "0x0000000000000000000000000000000000000000",
    "token1Address": "0x078D782b760474a361dDA0AF3839290b0EF57AD6",
    "nftTokenId": "1833079",
    "liquidityPercentageToDecrease": 25,
    "simulateTransaction": false
}'

Key parameters

ParameterDescription
liquidityPercentageToDecreaseInteger from 1–100. Percentage of the position to withdraw.
withdrawAsWethUniswap v3 only. If false, unwraps WETH to native ETH in the withdrawal. Not applicable to Uniswap v4.
slippageToleranceOptional. Decimal slippage tolerance.

v3 fee collection: For Uniswap v3, uncollected fees are included in the withdrawal automatically via the SDK's removeCallParameters. You do not need to call /lp/claim separately.

Collecting Fees — /lp/claim

Collects accumulated trading fees from a Uniswap v3 or Uniswap v4 position. Not available for Uniswap v2; Uniswap v2 fees are embedded in LP token value and are realized upon liquidity removal.

curl --location 'https://api.uniswap.org/lp/claim' \
--header 'Content-Type: application/json' \
--header 'x-api-key: XXXXX' \
--data '{
    "protocol": "V4",
    "walletAddress": "XXXX",
    "chainId": 130,
    "tokenId": "1833079",
    "simulateTransaction": false
}'

How it works

  • Uniswap v3: Generates a collect call via the NonfungiblePositionManager. For positions involving native ETH (when collectAsWeth is false), generates a multicall of collect, unwrapWETH9, and sweepToken. Uncollected fee amounts from the Data API are used as minimum amounts for sandwich protection.
  • Uniswap v4: Generates a zero-liquidity decrease via the v4 PositionManager followed by TAKE_PAIR to sweep all collected fees.

Key parameters

ParameterDescription
protocolV3 or V4. Sending V2 returns a validation error.
tokenIdNFT token ID identifying the Uniswap v3 or Uniswap v4 position.
collectAsWethUniswap v3 only. If false, unwraps WETH to native ETH. Not applicable to Uniswap v4.
simulateTransactionIf true, includes gas fee estimates in the response.

Response

interface ClaimFeesResponse {
  token0: TokenAmount;
  token1: TokenAmount;
  claim: TransactionRequest;
  gasFeeEstimates?: GasFeeEstimates; // present when simulateTransaction: true
}

Schema Reference

TransactionRequest

All LP endpoints return a fully-formed TransactionRequest object ready for signing and broadcasting:

interface TransactionRequest {
  to: string;                    // Contract address to call
  from: string;                  // User's wallet address
  data: string;                  // Encoded calldata (hex string)
  value: string;                 // Native token amount (wei)
  chainId: number;
  gasLimit?: string;
  maxFeePerGas?: string;
  maxPriorityFeePerGas?: string;
  gasPrice?: string;             // Legacy gas price
}

Critical field: data

The data field contains the encoded contract call and must always be present in LP transactions.

  • Never Empty: The data field must be a non-empty hex string (not "" or "0x").
  • Never Modify: The API returns pre-validated calldata. Modifying it may cause funds to be lost or onchain reverts.
  • Always Validate: Check data exists before broadcasting.

TokenAmount

interface TokenAmount {
  tokenAddress: string;
  amount: string; // in wei / smallest token unit
}

ApprovalTransactionRequest

Returned by /lp/approve when approvals are needed:

interface ApprovalTransactionRequest extends TransactionRequest {
  token: string;      // Token address being approved
  spender: string;    // Spender contract address
}

BatchPermitData (Uniswap v4)

interface BatchPermitData {
  domain: TypedDataDomain;
  types: Record<string, TypedDataField[]>;
  values: PermitBatch;
}

Error Handling

HTTP status codes

CodeMeaning
200Request succeeded
400Invalid request (validation error)
401Invalid API key
429Rate limit exceeded
500API error (retry with backoff)
503Temporary unavailability (retry)

Error response format

interface ErrorResponse {
  error: string;
  message: string;
  details?: Record<string, any>;
}

Common errors

v2 fee claim attempt

Cause: Calling /lp/claim with protocol: "V2"

Solution: Uniswap v2 fees are realized by calling /lp/decrease. Use /lp/claim only for Uniswap v3 and Uniswap v4 positions.

Pool not found

Cause: The specified pool does not exist onchain for the given token pair, fee tier, and chain

Solutions:

  • Verify token addresses are correct and checksummed
  • Confirm the poolReference (pool address or pool ID) is correct for the target protocol
  • Use newPool instead of existingPool to initialize a new pool

Insufficient liquidity

Cause: The computed dependent token amount exceeds available balances or position bounds

Solutions:

  • Verify token balances before calling the LP endpoint
  • Adjust the independentToken amount
  • Widen the price range for concentrated liquidity positions

Validation error

Cause: Invalid or missing request parameters

Solutions:

  • Ensure all required fields are present for the chosen protocol
  • Verify addresses are valid checksummed hex strings
  • Confirm amounts are in the correct units (wei, not ether)
  • Ensure liquidityPercentageToDecrease is an integer between 1 and 100

Authentication error

Cause: Invalid or missing x-api-key header

Solutions:

  • Include the x-api-key header in every request
  • Confirm the API key was copied correctly (case-sensitive)

Transaction revert scenarios

If a transaction reverts onchain:

  1. Check data field: Verify it is not empty before broadcasting
  2. Verify token balances: User has sufficient token balances at broadcast time
  3. Check approvals: Run /lp/approve again — a prior approval may have been consumed or revoked
  4. Check slippage: Pool price moved beyond the slippage tolerance between quote and broadcast
  5. Check deadline: Transaction was not broadcast before the deadline encoded in the calldata
  6. Nonce collision: Another transaction used the same nonce
async function validateBeforeBroadcast(
  tx: TransactionRequest,
  provider: Provider,
  token: string,
  amount: string
): Promise<void> {
  // 1. Validate transaction structure
  if (!tx.data || tx.data === '' || tx.data === '0x') {
    throw new Error('Invalid transaction: empty data field');
  }

  // 2. Check native balance
  const balance = await provider.getBalance(tx.from);
  if (balance.lt(tx.value)) {
    throw new Error('Insufficient native token balance');
  }

  // 3. Check ERC-20 balance (if applicable)
  if (token !== NATIVE_TOKEN_ADDRESS) {
    const tokenContract = new Contract(token, ERC20_ABI, provider);
    const tokenBalance = await tokenContract.balanceOf(tx.from);
    if (tokenBalance.lt(amount)) {
      throw new Error('Insufficient token balance');
    }
  }

  // 4. Simulate transaction (recommended)
  try {
    await provider.call(tx);
  } catch (error) {
    throw new Error(`Transaction simulation failed: ${error.message}`);
  }
}

Best Practices

Always check approvals first

Call /lp/approve before every LP action — even for positions where approvals were previously granted, since allowances can be revoked or consumed.

async function approveAndExecute(
  approvalParams: ApprovalRequest,
  lpAction: () => Promise<TransactionRequest>
): Promise<string> {
  const { approvals, permitData } = await fetchApprovals(approvalParams);

  // Execute any onchain approval transactions
  for (const approval of approvals) {
    const signedApproval = await wallet.signTransaction(approval);
    await provider.sendTransaction(signedApproval);
  }

  // Sign permit offchain if returned
  let permitSignature: string | undefined;
  if (permitData) {
    permitSignature = await wallet._signTypedData(
      permitData.domain, permitData.types, permitData.values
    );
  }

  const lpTx = await lpAction(); // e.g. /lp/create with permitSignature included
  validateTransaction(lpTx);
  const signedTx = await wallet.signTransaction(lpTx);
  return provider.sendTransaction(signedTx);
}

Price range guidance

When using priceBounds, note that the API snaps prices to valid tick spacing boundaries. Always display the adjusted prices returned in the response to the user — not the original input values.

const { minPrice, maxPrice, tickLower, tickUpper } = createResponse;
// Show minPrice / maxPrice to the user, not the original priceBounds input

Slippage configuration

SettingToleranceUse Case
Conservative0.05–0.5%Stable pairs, low volatility
Moderate0.5–1%Most LP actions
Aggressive1–5%Volatile pairs, wide price ranges, large positions

Transaction freshness

LP transactions are time-sensitive due to pool price movement:

const TX_EXPIRY_MS = 30_000; // 30 seconds

const txTimestamp = Date.now();
// ... user reviews amounts ...
if (Date.now() - txTimestamp > TX_EXPIRY_MS) {
  lpTx = await refetchLpTransaction(params); // Fetch a fresh transaction
}

Gas management

Use simulateTransaction: true on /lp/create, /lp/increase, /lp/decrease, and /lp/claim to receive gas estimates from the API. Additionally:

  • Update gas prices: Fetch fresh gas prices from your RPC before broadcasting
  • Handle gas spikes: Warn users when gas is unusually high
  • EIP-1559 vs Legacy: Prefer EIP-1559 (maxFeePerGas / maxPriorityFeePerGas) on supported chains

Transaction validation

Always validate the transaction payload before broadcasting:

function validateLpTransaction(tx: TransactionRequest): void {
  if (!tx.data || tx.data === '' || tx.data === '0x') {
    throw new Error('Transaction data is empty');
  }
  if (!tx.to || !isAddress(tx.to)) {
    throw new Error('Invalid recipient address');
  }
  if (!tx.from || !isAddress(tx.from)) {
    throw new Error('Invalid sender address');
  }
  if (tx.maxFeePerGas && tx.gasPrice) {
    throw new Error('Cannot set both maxFeePerGas and gasPrice');
  }
}

Error recovery

Implement retry logic with exponential backoff for transient failures:

async function fetchLpTxWithRetry(
  endpoint: string,
  params: object,
  maxRetries = 3
): Promise<any> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(`https://api.uniswap.org${endpoint}`, {
        method: 'POST',
        headers: {
          'x-api-key': API_KEY,
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        body: JSON.stringify(params)
      });

      if (!response.ok) {
        if (response.status === 429) {
          await sleep(Math.pow(2, attempt) * 1000);
          continue;
        }
        throw new Error(`API error: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
      await sleep(Math.pow(2, attempt) * 1000);
    }
  }
  throw new Error('Max retries exceeded');
}

Monitoring & logging

Track key metrics to maintain production reliability:

function logLpAttempt(
  endpoint: string,
  params: object,
  response: object,
  txHash?: string,
  error?: Error
): void {
  analytics.track('lp_attempt', {
    timestamp: Date.now(),
    endpoint,
    protocol: (params as any).protocol,
    chainId: (params as any).chainId,
    txHash,
    success: !!txHash && !error,
    error: error?.message
  });
}

Troubleshooting

Position creation issues

Problem: API returns unexpected token amounts

  • Verify the amount is in the correct units (wei, not ether)
  • Confirm token decimals match the onchain contract
  • If using priceBounds, check the returned minPrice / maxPrice in the response — the server may have snapped to different tick boundaries than expected
  • For new pools, confirm initialPrice is a valid sqrtRatioX96 value

Problem: Transaction reverts after a successful create response

  • Re-check token approvals via /lp/approve — another transaction may have consumed the allowance
  • Confirm the quote has not gone stale (price moved significantly since the transaction was built)
  • Verify slippage tolerance is appropriate for the pair's volatility

Liquidity management issues

Problem: /lp/increase returns a mismatched dependent token amount

  • Confirm the nftTokenId is correct and belongs to the specified wallet
  • Verify pool state has not changed significantly between the quote and the time amounts are displayed to the user
  • Ensure token0Address / token1Address match the order in the existing position

Problem: /lp/decrease does not return expected amounts

  • Confirm liquidityPercentageToDecrease is between 1 and 100
  • For Uniswap v3, note that uncollected fees are bundled into the withdrawal — the returned amounts may be higher than the pro-rata liquidity alone

Fee collection issues

Problem: /lp/claim returns zero amounts

  • Confirm the position has accumulated fees since the last collection
  • Verify tokenId corresponds to an active Uniswap v3 or Uniswap v4 position
  • Check that the Data API has indexed the latest onchain state for the position

Problem: Uniswap v2 claim attempt returns a validation error

  • This is expected behavior. Uniswap v2 fees are not claimable independently — use /lp/decrease to realize accumulated fees along with liquidity.

Approval issues

Problem: Permit signature rejected onchain

  • Some signing libraries require an explicit EIP712Domain type in the types object. Add it if your library does not inject it automatically:
const typesWithDomain = {
  EIP712Domain: [
    { name: 'name', type: 'string' },
    { name: 'version', type: 'string' },
    { name: 'chainId', type: 'uint256' },
    { name: 'verifyingContract', type: 'address' }
  ],
  ...permitData.types
};

signature = await wallet._signTypedData(
  permitData.domain,
  typesWithDomain,
  permitData.values
);

Problem: Onchain approval transaction reverts

  • Check that gasLimit is sufficient for the approval
  • Confirm the token contract supports the standard ERC-20 approve interface
  • For fee-on-transfer tokens, verify the spender contract handles them correctly

API issues

Problem: 429 Rate Limit Exceeded

Implement request caching for repeated queries on the same position:

const cache = new Map<string, { data: any; timestamp: number }>();

async function fetchWithCache(
  endpoint: string,
  params: object,
  cacheDuration = 15_000
): Promise<any> {
  const key = `${endpoint}:${JSON.stringify(params)}`;
  const cached = cache.get(key);
  if (cached && Date.now() - cached.timestamp < cacheDuration) {
    return cached.data;
  }
  const data = await fetchLpTxWithRetry(endpoint, params);
  cache.set(key, { data, timestamp: Date.now() });
  return data;
}

Limitations

  • Uniswap v2 fee claiming: Not supported. Fees are embedded in LP tokens and realized via /lp/decrease.
  • Uniswap v4 hooks: Supported in /lp/create via the hooks field in newPool. Hook compatibility is the caller's responsibility.
  • UniswapX: Not applicable. The LP API operates exclusively on AMM positions.
  • Migrate action: Migration is supported via dedicated migration endpoints. Also supported via /lp/approve with action: "MIGRATE". Migration transaction building is handled separately. See migrating LP position.
  • Chain support: See Supported Chains for the full list of available networks per protocol version.

Support

For support, reach out via the help link in the Uniswap Developer Platform.

When reporting issues, include:

  • Request ID from the API response
  • Full request/response payloads (sanitize sensitive data such as wallet addresses if needed)
  • Protocol version and chain ID
  • Transaction hash (if the transaction was broadcast)
  • Timestamp of the request