Integration Quickstart
Add leverage to your platform in 4 API calls.
The Lavarage API lets you embed leveraged trading into any Solana application. You call the API to build an unsigned Solana transaction, the user signs it with their wallet, and you submit it to the network. That's it — no on-chain program knowledge required.
What you get:
- Unsigned VersionedTransactions ready to sign and submit
- Automatic offer matching — no need to find liquidity pools manually
- Support for any SPL token that has an active offer
- Both LONG and SHORT positions are fully supported
Base URL: https://api.lavarage.xyz
Prerequisites
- An API key — apply at https://lavarage.xyz/partners or submit
POST /api/v1/partners/apply - A Solana wallet adapter (or any signing implementation) on the client side
- A Solana RPC endpoint for transaction submission (Helius, Triton, or your own node)
Authentication
Trading and partner management endpoints require an API key in the x-api-key header:
curl https://api.lavarage.xyz/api/v1/positions \
-H "x-api-key: YOUR_API_KEY"To get an API key, apply at https://lavarage.xyz/partners or submit POST /api/v1/partners/apply. Once approved, generate keys via the Partners API:
curl -X POST https://api.lavarage.xyz/api/v1/partners/keys \
-H "x-api-key: YOUR_API_KEY"The raw key is only returned once — store it securely.
Key management:
- List keys:
GET /api/v1/partners/keys - Revoke a key:
DELETE /api/v1/partners/keys/:id(permanent and immediate)
Public Endpoints (No Key Required)
| Endpoint | Description |
|---|---|
GET /health | Service health check |
GET /api/v1/offers | Browse liquidity pools |
GET /api/v1/offers/utilization | Pool utilization metrics |
GET /api/v1/offers/:publicKey | Single offer details |
GET /api/v1/tokens | Token list with prices |
GET /api/v1/tokens/:address | Single token details |
POST /api/v1/offers/match | Match best offer for token pair |
GET /api/v1/offers/top | Top tokens by activity |
GET /api/v1/offers/latest | Latest tokens |
GET /api/v1/referral/* | Referral read endpoints |
Wallet Signature Authentication
Some endpoints (orders, referral writes) require wallet signature authentication via 3 headers:
| Header | Value |
|---|---|
x-wallet-address | Your Solana wallet address (base58) |
x-wallet-signature | Ed25519 signature of the message (base58) |
x-wallet-message | The signed message: lavarage:<wallet>:<timestamp_ms> |
import nacl from 'tweetnacl';
import bs58 from 'bs58';
const wallet = keypair; // Your Solana Keypair
const timestamp = Date.now().toString();
const message = `lavarage:${wallet.publicKey.toBase58()}:${timestamp}`;
const messageBytes = new TextEncoder().encode(message);
const signature = nacl.sign.detached(messageBytes, wallet.secretKey);
const headers = {
'x-wallet-address': wallet.publicKey.toBase58(),
'x-wallet-signature': bs58.encode(signature),
'x-wallet-message': message,
};Security Best Practices
- Never expose API keys in client-side code
- Use environment variables for key storage
- Rotate keys periodically using the Partners API
- Revoke compromised keys immediately
Rate Limits
| Endpoint Group | Limit |
|---|---|
| Transaction endpoints (open, close, split, merge, increase-borrow, add-collateral) | 600 requests / 60s |
| Read endpoints (positions, offers, tokens) | 1800 requests / 60s |
| Public endpoints (no auth) | 30 requests / 60s per IP |
Exceeding the limit returns HTTP 429 with code RATE_LIMIT_EXCEEDED. Implement exponential backoff starting at 1s.
Your First Trade
Step 1: Find a Market
Call POST /api/v1/positions/quote-by-token to get a price preview and confirm a market exists for your token. This does not build a transaction — it just returns quote data.
curl -X POST https://api.lavarage.xyz/api/v1/positions/quote-by-token \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"baseTokenMint": "So11111111111111111111111111111111111111112",
"userPublicKey": "GsbwXfJraMomNxBcjK7xK2xQx5MQgQx4Ld8QkLeNmA3v",
"collateralAmount": "1000000000",
"leverage": 3,
"side": "LONG"
}'Response:
{
"inAmount": "1000000000",
"outAmount": "2950000000",
"priceImpactPct": "0.12",
"otherAmountThreshold": "2920500000",
"inputMint": "So11111111111111111111111111111111111111112",
"outputMint": "So11111111111111111111111111111111111111112",
"slippageBps": 50
}Step 2: Build the Transaction
Call POST /api/v1/positions/open-by-token to build the unsigned transaction. The server resolves the best liquidity pool automatically.
curl -X POST https://api.lavarage.xyz/api/v1/positions/open-by-token \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"baseTokenMint": "So11111111111111111111111111111111111111112",
"userPublicKey": "GsbwXfJraMomNxBcjK7xK2xQx5MQgQx4Ld8QkLeNmA3v",
"collateralAmount": "1000000000",
"leverage": 3,
"side": "LONG",
"slippageBps": 50
}'Response:
{
"transaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAkP...",
"positionAddress": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
"lastValidBlockHeight": 285432100,
"quote": { "outAmount": "9950000000", "priceImpactPct": 0.12, "slippageBps": 50 }
}The transaction field is a base58-encoded VersionedTransaction.
Step 3: User Signs and Submits
Deserialise the transaction, have the user sign it, and submit to the network.
import { VersionedTransaction, Connection } from '@solana/web3.js'
import bs58 from 'bs58'
// Deserialise
const txBytes = bs58.decode(response.transaction)
const tx = VersionedTransaction.deserialize(txBytes)
// Sign with the user's wallet (Phantom, Solflare, etc.)
const signedTx = await wallet.signTransaction(tx)
// Submit
const connection = new Connection('https://api.mainnet-beta.solana.com')
const signature = await connection.sendRawTransaction(signedTx.serialize())
await connection.confirmTransaction(signature, 'confirmed')
console.log('Position opened:', signature)Step 4: Monitor and Close
Poll GET /api/v1/positions?owner=<wallet>&status=OPEN to monitor open positions, then build a close transaction when ready.
# Get a close quote first
curl -X POST https://api.lavarage.xyz/api/v1/positions/close-quote \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"positionAddress": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
"userPublicKey": "GsbwXfJraMomNxBcjK7xK2xQx5MQgQx4Ld8QkLeNmA3v"
}'
# Then build the close transaction
curl -X POST https://api.lavarage.xyz/api/v1/positions/close \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"positionAddress": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
"userPublicKey": "GsbwXfJraMomNxBcjK7xK2xQx5MQgQx4Ld8QkLeNmA3v",
"slippageBps": 50
}'Sign and submit the returned transaction field the same way as Step 3.
Response Format
Transaction-building endpoints return a transaction field (base58-encoded unsigned VersionedTransaction) plus endpoint-specific fields:
| Endpoint | Response shape |
|---|---|
POST /positions/open | { transaction, positionAddress, lastValidBlockHeight, quote } |
POST /positions/open-by-token | { transaction, positionAddress, lastValidBlockHeight, quote } |
POST /positions/close | { transaction, lastValidBlockHeight, quote } |
POST /positions/split | { transaction, lastValidBlockHeight, newPositionAddresses } |
POST /positions/partial-sell | { splitTransaction, closeTransaction, newPositionAddresses, swapQuote } |
POST /positions/repay | { transaction, lastValidBlockHeight } |
POST /positions/partial-repay | { transaction, lastValidBlockHeight } |
The transaction is unsigned — you are responsible for having the user sign it and submitting it to the Solana network. Lavarage never holds private keys for your users.
Versioning
The current API version is v1. All endpoints are prefixed with /api/v1/. Breaking changes will be released under a new version prefix (/api/v2/) with a deprecation period.
What's Next
- Trading API — Full endpoint reference for quotes, opening, closing, and monitoring positions
- Advanced Operations — Split, partial sell, repay, TP/SL orders
- Revenue & Fees — How partner fee sharing works
- Real-Time Data — SSE streams and webhook notifications
- Error Reference — Complete error code table with retry guidance
Updated 2 days ago