Stream Quotes
WS /api/v1/stream is a WebSocket endpoint that pushes live swap quotes. Subscribe to one or
more token pairs and the server sends an updated quote whenever the on-chain price for that pair
materially changes — no polling required.
Use streaming when you need a continuously up-to-date price (e.g. a swap UI showing a live rate).
For one-off quotes,
GET /api/v1/quote is simpler.Connecting
This endpoint requires an API key like every other endpoint (see Authentication) — but since browsers can’t set custom headers on a WebSocket handshake, the key must be passed as a?key= query parameter, not an Authorization
header. A handshake without a valid key is rejected before the upgrade completes. The upgrade is guarded by
the pre-auth per-IP limiter only — the per-plan key limits that apply to REST endpoints are
not applied to the handshake (see Rate Limits). Once upgraded, the
connection is long-lived and is not subject to any per-request rate limiter.
Client messages
Send a JSON text frame with anop and a pairs array.
string
required
Operation to perform:
subscribe or unsubscribe for quote streaming, or
subscribe_route / unsubscribe_route for CPI route templates (see
Route templates below).object[]
required
One or more pair specifications to subscribe or unsubscribe.
(in, out, amount, exactIn) tuple — two subscriptions that
differ only in amount are distinct streams.
Subscribe
subscribed ack. The first quote may arrive
just before the ack.
Unsubscribe
Route templates
subscribe_route streams a ready-to-use CPI route template instead of a price. It is aimed at
on-chain integrators (liquidation keepers, vault rebalancers) that want to fire without an HTTP
round-trip: hold the latest template in memory and submit when your trigger fires.
Send a routes array whose entries use the same request shape as
POST /api/v1/cpi/route-accounts:
swapMode defaults to ExactIn. slippageBps, allowedIntermediateMints, maxHops,
excludeDexes and referrer are optional and behave exactly as on the REST endpoint.
Route subscriptions are capped separately from quote subscriptions: 32 per connection
(quotes allow 256). Each template is materially more expensive to maintain than a quote.
Server messages
Quote push
Sent for the immediate first quote and again only when the quote materially changes (a change inamountOut, priceImpactBps, or hops). Identical re-quotes are suppressed.
string
Always
"quote".string
Input token mint.
string
Output token mint.
string
The subscribed amount, in smallest units.
string
Estimated output amount in smallest units (ExactIn) — the live quote.
integer
Price impact in basis points.
integer
Number of hops in the route. 1 = direct, 2+ = multi-hop.
integer
The Fogo slot the quote was computed at.
string
Firm-quote commitment ID for this exact quote. Pass it as
quoteId to
POST /swap or POST /instructions
to replay the quoted route at the quoted price. Omitted when the quote can’t be pinned.
See Firm quotes.integer
How long
quoteId stays redeemable, in milliseconds.integer
How long
quoteId stays redeemable with firm: true (price-or-fail), in milliseconds.string
Base58 Ed25519 signature over the canonical
vulcx-quote-v1 message, present when the server has
a signing key. Verify offline against the key at /.well-known/vulcx-quote-signer.integer
Absolute expiry (unix milliseconds) embedded in the signed message.
Route push
Sent for the first template onsubscribe_route, then only when the template materially changes
— the route plan, account list, or LUTs. Amount movements alone do not trigger a push.
string
Always
"route".string
The authority the template was built for.
string
Input token mint.
string
Output token mint.
string
The subscribed amount, in smallest units.
string
ExactIn or ExactOut.integer
Increases by 1 per template change for this subscription. A gap means you missed a push —
resubscribe to resynchronise.
integer
The Fogo slot the template was built at.
object
The same payload
POST /cpi/route-accounts returns:
the ready routeInstruction, requiredTokenAccounts, referrerAta, and
addressLookupTableAddresses.Invalidate push
Sent when the last quote pushed for a pair drifts past the firm margin before a fresh quote push replaces it — the firm window on thatquoteId is effectively dead, so don’t redeem it with
firm: true. This is best-effort UX sugar: the redemption-time check on the server is the real
gate, so you may still occasionally get a 409 without having seen an invalidate.
string
Always
"invalidate".string
The commitment ID that drifted stale.
Acknowledgement
Sent in response to asubscribe / unsubscribe, or to report a problem with a message.
string
"subscribed", "unsubscribed", or "error".string
Present on errors — e.g.
"invalid json", "unknown op".integer
Number of pairs accepted by a subscribe/unsubscribe. Invalid or duplicate pairs are skipped and not counted.