Position Health Management
Increase borrow, compound, and add collateral to manage position health.
Position Health Management
When a position's LTV drops below the pool's open LTV (e.g. price appreciation), you have excess borrowing capacity. When a position approaches liquidation, you can add collateral to improve health. These endpoints let you manage position health programmatically.
Concepts
- LTV (Loan-to-Value): debt / collateral value. Lower = healthier.
- Open LTV: maximum LTV the pool allows for borrowing (e.g. 78% = 7800 bps).
- Liquidation LTV: threshold where the position gets liquidated (e.g. 90%).
- Headroom: when current LTV is well below liquidation LTV, you can borrow more.
Step 1: Check Borrow Headroom
curl -X POST https://api.lavarage.xyz/api/v1/positions/increase-borrow-quote \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"positionAddress": "YOUR_POSITION",
"userPublicKey": "YOUR_WALLET",
"mode": "withdraw"
}'Response includes:
maxAdditionalBorrow— max you can borrow in quote token smallest unitscurrentLTV/projectedLTV— LTV before and after borrowing maxhasHeadroom— true if position has meaningful borrowing capacitypriceScenarios— what-if table showing PnL and LTV at various price changes
Step 2a: Withdraw (Borrow More)
Borrow additional quote tokens and receive them in your wallet:
curl -X POST https://api.lavarage.xyz/api/v1/positions/increase-borrow \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"positionAddress": "YOUR_POSITION",
"userPublicKey": "YOUR_WALLET",
"additionalBorrowAmount": "500000000",
"mode": "withdraw"
}'Sign and submit the returned transaction. Your debt increases and you receive the quote tokens.
Step 2b: Compound (Re-Leverage)
Borrow more, swap to base token via Jupiter, and deposit as additional collateral — all in one transaction:
# First get a compound quote to see the swap estimate
curl -X POST https://api.lavarage.xyz/api/v1/positions/increase-borrow-quote \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"positionAddress": "YOUR_POSITION",
"userPublicKey": "YOUR_WALLET",
"mode": "compound",
"slippageBps": 50
}'
# Then build the transaction
curl -X POST https://api.lavarage.xyz/api/v1/positions/increase-borrow \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"positionAddress": "YOUR_POSITION",
"userPublicKey": "YOUR_WALLET",
"additionalBorrowAmount": "500000000",
"mode": "compound",
"slippageBps": 50,
"astralaneTipLamports": 10000
}'Compound mode includes a Jupiter swap, so it supports MEV protection via astralaneTipLamports. Submit the signed transaction via POST /api/v1/bundle/submit with mevProtect: true.
The compound quote's jupiterQuote.outAmount tells you how many base tokens you'll receive. The projectedLTV accounts for both the increased debt and the new collateral.
Step 3: Add Collateral (Rescue from Liquidation)
If your position is approaching liquidation, add more base tokens as collateral:
# Get quote to see projected LTV improvement
curl -X POST https://api.lavarage.xyz/api/v1/positions/add-collateral-quote \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"positionAddress": "YOUR_POSITION",
"userPublicKey": "YOUR_WALLET",
"collateralAmount": "1000000000"
}'
# Build the transaction
curl -X POST https://api.lavarage.xyz/api/v1/positions/add-collateral \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"positionAddress": "YOUR_POSITION",
"userPublicKey": "YOUR_WALLET",
"collateralAmount": "1000000000"
}'The collateral amount is in the base token's smallest units. The add-collateral quote response includes baseTokenAddress and baseDecimals so you know which token to send and at what precision.
Automation Example: Auto-Compound Bot
// Poll positions and auto-compound when headroom is available
async function autoCompound(positionAddress: string, wallet: Keypair) {
const quote = await fetch(`${API_BASE}/api/v1/positions/increase-borrow-quote`, {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
positionAddress,
userPublicKey: wallet.publicKey.toBase58(),
mode: 'compound',
slippageBps: 100,
}),
}).then(r => r.json());
if (!quote.hasHeadroom || Number(quote.maxAdditionalBorrow) <= 0) return;
const { transaction } = await fetch(`${API_BASE}/api/v1/positions/increase-borrow`, {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
positionAddress,
userPublicKey: wallet.publicKey.toBase58(),
additionalBorrowAmount: quote.maxAdditionalBorrow,
mode: 'compound',
slippageBps: 100,
}),
}).then(r => r.json());
const tx = VersionedTransaction.deserialize(bs58.decode(transaction));
tx.sign([wallet]);
const sig = await connection.sendRawTransaction(tx.serialize());
console.log('Compounded:', sig);
}Updated 2 months ago