Real-Time Events (SSE)
Subscribe to live price, offer, and position updates via Server-Sent Events.
Overview
The SSE endpoint streams real-time updates without polling. It uses the standard browser EventSource API.
Endpoint: GET /api/v1/sse
Authentication: None required. The stream only emits public data (prices, offer updates) and position status changes (no sensitive fields).
Connecting
const es = new EventSource('https://api.lavarage.xyz/api/v1/sse?owner=YOUR_WALLET')
es.onopen = () => console.log('Connected')
es.onerror = () => {
es.close()
setTimeout(reconnect, 5_000) // reconnect after 5s on error
}Query parameter: owner=<wallet_address> — when provided, position events are filtered to only deliver updates for positions owned by that wallet.
Event Types
prices
pricesEmitted every ~10 seconds with updated token prices.
es.addEventListener('prices', (e) => {
const prices: Record<string, string> = JSON.parse(e.data)
// { "So111...": "152.40", "EPjFW...": "1.0001" }
updatePriceStore(prices)
})positions
positionsEmitted when a monitored position changes status (e.g. SUBMITTED → ONCHAIN, or position closed/liquidated).
es.addEventListener('positions', (e) => {
const updates = JSON.parse(e.data) // array of changed positions
invalidatePositionsCache()
})offers
offersEmitted when offer/pool data changes (new offers, liquidity changes).
es.addEventListener('offers', () => {
invalidateOffersCache()
})heartbeat
heartbeatEmitted every 30 seconds to keep the connection alive through proxies. No data payload — safe to ignore.
Reconnection
The SSE spec handles automatic reconnection in browsers. In Node.js or custom clients, implement your own reconnect loop:
function connect(walletAddress?: string) {
const url = walletAddress
? `https://api.lavarage.xyz/api/v1/sse?owner=${walletAddress}`
: 'https://api.lavarage.xyz/api/v1/sse'
const es = new EventSource(url)
let reconnectTimer: ReturnType<typeof setTimeout>
es.onopen = () => clearTimeout(reconnectTimer)
es.onerror = () => {
es.close()
reconnectTimer = setTimeout(() => connect(walletAddress), 5_000)
}
es.addEventListener('prices', (e) => {
const prices = JSON.parse(e.data)
// handle price update
})
es.addEventListener('positions', (e) => {
const updates = JSON.parse(e.data)
// handle position update
})
es.addEventListener('offers', () => {
// handle offer update
})
return () => {
clearTimeout(reconnectTimer)
es.close()
}
}
const disconnect = connect('GsbwXfJraMomNxBcjK7xK2xQx5MQgQx4Ld8QkLeNmA3v')Notes
- The endpoint is throttle-exempt — no rate limits apply
- Price data arrives as a flat map of
mintAddress → usdPrice(string decimals) - Position events are filtered server-side when
?owner=is specified — only positions belonging to that wallet are sent - If the connection drops, existing subscriptions do not need to be re-registered — just reconnect
Updated 4 days ago