Partner API Overview
Authentication, rate limits, response formats, and error handling.
Authentication
All write endpoints and position queries require an API key in the x-api-key header:
curl https://api.lavarage.xyz/api/v1/positions \
-H "x-api-key: lava_live_abc123..."To get an API key, email [email protected] or generate one via the Partners API:
curl -X POST https://api.lavarage.xyz/api/v1/partners/keys \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"label": "my-integration"}'Public endpoints (offers, tokens, health) do not require authentication.
Rate Limits
| Endpoint Group | Limit |
|---|---|
| Transaction endpoints (open, close, split, merge) | 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.
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 } |
const { transaction, lastValidBlockHeight } = await res.json()
const tx = VersionedTransaction.deserialize(bs58.decode(transaction))
const signed = await wallet.signTransaction(tx)
const sig = await connection.sendRawTransaction(signed.serialize())
// Use lastValidBlockHeight to detect expiry — see Transaction Confirmation guideThe 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.
Error Format
All errors use a consistent structure:
{
"statusCode": 400,
"code": "POSITION_INSUFFICIENT_BALANCE",
"message": "Insufficient balance — you need enough collateral token + protocol fee (~1%), AND ~0.01 SOL for transaction fees and account rent.",
"detail": null,
"path": "/api/v1/positions/open-by-token",
"timestamp": "2026-03-15T12:00:00.000Z"
}The code field is a stable string — safe to match programmatically. The message is human-readable and may change between versions. Always match on code, not message.
See the Error Reference for the full list of error codes.
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.
Updated 4 days ago