GET /v1/quote/stream
Server-Sent-Events stream of the same ranked swap quote as POST /v1/quote, recomputed server-side on a timer and pushed to the client only when the best route's output has moved past a configurable threshold.
Designed as a drop-in replacement for client-side polling. Default tick rate is 2 Hz (500 ms), so updates arrive at least twice as fresh as a 1 Hz polling loop, and bandwidth stays lower because the server suppresses emissions when nothing has meaningfully changed.
Who this is for
- Trading bots watching a handful of pairs continuously — one open stream per pair replaces a polling loop, bypasses the per-minute quote rate limit on every tick, and gets sub-500 ms reaction time when an output moves.
- Swap UIs on Starter ($49) and Pro ($199) — the SSE connection budget (3 or 10 concurrent streams) leaves room for both
/v1/stream/pricesand/v1/quote/streamat the same time.
Free-tier users get one concurrent SSE slot shared across every stream route. A swap widget on the free tier that already holds a /v1/stream/prices connection will not be able to open /v1/quote/stream on top of it. In practice, free-tier integrators typically prioritize the price stream and keep using POST /v1/quote for one-shot refreshes.
Request
GET /v1/quote/stream?inputMint=SOL&outputMint=USDC&amount=1000000000&slippageBps=100
x-api-key: YOUR_API_KEYBrowser-native EventSource cannot set custom headers. For browser clients, use ?apiKey=YOUR_API_KEY instead.
Query parameters
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
inputMint | string | Yes | — | Base58 mint or token symbol (e.g. "SOL") |
outputMint | string | Yes | — | Base58 mint or token symbol |
amount | string | Yes | — | Amount in smallest units (positive integer) |
slippageBps | number | No | 100 | Slippage tolerance (1–5000 bps) |
tickHz | number | No | 2 | Server recompute rate in Hz, clamped to [1, 5] |
minMoveBps | number | No | 1 | Minimum change in bestRoute.outputAmount (in basis points) required to emit a new quote event |
Events
| Event | Description |
|---|---|
quote | Current ranked quote. First event is emitted synchronously on connect; subsequent events fire only when the best output moved by at least minMoveBps since the last emission. |
heartbeat | Connection keepalive, every 15 s |
error | Terminal error (e.g. initial quote 404). The stream closes immediately after. |
quote payload
Identical shape to the POST /v1/quote response — the full top-5 routes array, the bestRoute, and the echoed request parameters. Switching between polling and streaming requires no client-side type changes.
event: quote
data: {"routes":[...],"bestRoute":{"dex":"orca-whirlpool","poolAddress":"HJPj...","outputAmount":"134520000","priceImpactBps":0,"feeBps":4,"poolCacheAgeMs":250,"confidence":"observed"},"inputMint":"So11111111111111111111111111111111111111112","outputMint":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","amount":"1000000000","slippageBps":100,"poolsScanned":41}error payload
event: error
data: {"error":"No valid quotes available","status":404,"inputMint":"So1111...","outputMint":"EPjF..."}Route stability
The route may change between emissions. The server runs the full quote pipeline on every tick — direct, 2-hop, and 3-hop candidates are rescored, and the winning bestRoute is whichever scores highest now, not whichever was best on connect. This matches how client-side polling against POST /v1/quote behaves.
If you need a stable route for a given (inputMint, outputMint, amount) tuple — for example, to build a tx against the exact route you showed the user — use POST /v1/quote and pin its response on the client instead of subscribing to this stream.
Transient failures
If a tick hits a transient 404/503/504 (stale pool cache, bridge walker timeout), the tick is silently dropped and the stream stays open; the next tick retries. Clients will see a silence window between heartbeats instead of an error.
Only the initial quote can emit an error event and close the stream — persistent failures after connect are invisible beyond heartbeat cadence.
Example
curl -N -H "x-api-key: YOUR_API_KEY" \
"https://api.venum.dev/v1/quote/stream?inputMint=SOL&outputMint=USDC&amount=1000000000&slippageBps=100"
# Browser/EventSource
curl -N \
"https://api.venum.dev/v1/quote/stream?inputMint=SOL&outputMint=USDC&amount=1000000000&slippageBps=100&apiKey=YOUR_API_KEY"Errors
| Status | Description |
|---|---|
400 | Missing or invalid query parameters |
401 | Missing or invalid API key |
429 | SSE connection limit exceeded for your tier |
Post-connect terminal errors (initial 404) arrive as an error SSE event rather than an HTTP status.
Rate limit
The GET /v1/quote/stream connect request counts against the Quote per-minute rate limit (free 10/min, starter 60/min, pro 300/min). Once connected, server-side ticks do not count against that limit.
Concurrent open streams per API key count against the shared SSE streams connection limit (free 1, starter 3, pro 10) in Plans & Rate Limits. The same budget is shared across every SSE route: a Free-tier key with /v1/stream/prices open cannot also open /v1/quote/stream at the same time — Starter or Pro is required to hold both concurrently.
