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)
|
BlockchainAvailable Endpoints
| Endpoint | Description |
|---|---|
| POST /lp/approve | Check token approvals and return approval transactions |
| POST /lp/create | Create a new Uniswap v3 or Uniswap v4 liquidity position |
| POST /lp/create_classic | Create a new Uniswap v2 liquidity position |
| POSTÂ /lp/increase | Add liquidity to an existing Uniswap v2, v3, or v4Â position |
| POSTÂ /lp/decrease | Remove liquidity from an existing Uniswap v2, v3, or v4Â position |
| POSTÂ /lp/claim | Collect 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:
| Protocol | Positions | Fee Claiming | Full-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/claimwithprotocol: "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
| Parameter | Description |
|---|---|
protocol | V2, V3, or V4 |
chainId | The blockchain network |
lpTokens | Array of { tokenAddress, amount }Â objects |
action | CREATE, INCREASE, DECREASE, or MIGRATE |
generatePermitAsTransaction | If 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. Includestoken0address,token1address, andpoolReference(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, optionalhooks(Uniswap v4 only), andinitialPriceas asqrtRatioX96string. 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
0x0000000000000000000000000000000000000000for native ETH token addresses. The API will generate a multicall that includesrefundETHto return any excess ETH to the caller.
For Uniswap v4 permit-based approvals, include v4BatchPermitData and signature from the approval flow.
Key parameters
| Parameter | Description |
|---|---|
protocol | V2, V3, or V4 |
chainTd | The blockchain network |
token0Address / token_1_address | The token pair addresses |
nftTokenId | Required for Uniswap v3 and Uniswap v4. NFT token ID identifying the position. |
independentToken | Token address and amount the user wants to add |
slippageTolerance | Optional. 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
| Parameter | Description |
|---|---|
liquidityPercentageToDecrease | Integer from 1–100. Percentage of the position to withdraw. |
withdrawAsWeth | Uniswap v3 only. If false, unwraps WETH to native ETH in the withdrawal. Not applicable to Uniswap v4. |
slippageTolerance | Optional. 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
collectcall via theNonfungiblePositionManager. For positions involving native ETH (whencollectAsWethisfalse), generates a multicall ofcollect,unwrapWETH9, andsweepToken. 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
PositionManagerfollowed byTAKE_PAIRto sweep all collected fees.
Key parameters
| Parameter | Description |
|---|---|
protocol | V3 or V4. Sending V2 returns a validation error. |
tokenId | NFT token ID identifying the Uniswap v3 or Uniswap v4Â position. |
collectAsWeth | Uniswap v3 only. If false, unwraps WETH to native ETH. Not applicable to Uniswap v4. |
simulateTransaction | If 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
datafield 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
dataexists 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
| Code | Meaning |
|---|---|
| 200 | Request succeeded |
| 400 | Invalid request (validation error) |
| 401 | Invalid APIÂ key |
| 429 | Rate limit exceeded |
| 500 | API error (retry with backoff) |
| 503 | Temporary 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
newPoolinstead ofexistingPoolto 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
liquidityPercentageToDecreaseis an integer between 1 and 100
Authentication error
Cause: Invalid or missing x-api-key header
Solutions:
- Include the
x-api-keyheader in every request - Confirm the API key was copied correctly (case-sensitive)
Transaction revert scenarios
If a transaction reverts onchain:
- Check
datafield: Verify it is not empty before broadcasting - Verify token balances: User has sufficient token balances at broadcast time
- Check approvals: Run
/lp/approveagain — a prior approval may have been consumed or revoked - Check slippage: Pool price moved beyond the slippage tolerance between quote and broadcast
- Check deadline: Transaction was not broadcast before the deadline encoded in the calldata
- Nonce collision: Another transaction used the same nonce
Recommended pre-broadcast validation
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 inputSlippage configuration
| Setting | Tolerance | Use Case |
|---|---|---|
| Conservative | 0.05–0.5% | Stable pairs, low volatility |
| Moderate | 0.5–1% | Most LP actions |
| Aggressive | 1–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 returnedminPrice/maxPricein the response — the server may have snapped to different tick boundaries than expected - For new pools, confirm
initialPriceis a validsqrtRatioX96Â 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
nftTokenIdis 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/token1Addressmatch the order in the existing position
Problem: /lp/decrease does not return expected amounts
- Confirm
liquidityPercentageToDecreaseis 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
tokenIdcorresponds 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/decreaseto realize accumulated fees along with liquidity.
Approval issues
Problem: Permit signature rejected onchain
- Some signing libraries require an explicit
EIP712Domaintype 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
gasLimitis 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/createvia thehooksfield innewPool. 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/approvewithaction: "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