POST /quote, then receive a quote frame every time pricing revises it, until you submit an order or the session ends. Use it instead of re-polling POST /quote when you need a quote that stays fresh, for example while a user reviews a trade.
Endpoint: wss://flash.definitive.fi/v1/ws
Each quote payload is the same shape as the POST /quote response, so an existing quote-handling path works unchanged. Every revision is a complete replacement, with its own quoteId and signing payloads: sign and submit the newest one.
Connection handling (authentication, multiplexing, heartbeats, reconnecting, connection limits, and connection-level errors) is covered in Connection. This page documents the quotes channel.
Why subscribe instead of polling
- Faster first quote. A subscription streams the first quote that passes our pricing checks instead of waiting for multiple routes to compare, so it typically arrives sooner than a
POST /quoteresponse — and it is immediately signable. - Better quotes follow. As deeper routing completes, better-priced revisions arrive on the same subscription. You get the fast quote and the well-priced quote, in that order, without choosing between them.
- Stays executable while the user decides. Each revision carries fresh signing payloads, so the quote on screen when the user confirms is one they can actually submit — no re-polling loop needed.
Working with the quotes channel
- You choose the
subscriptionId. It labels every frame for that subscription and must be unique among your live subscriptions on that connection. - One connection can hold many quote subscriptions. Each one is an independent quote session, so run one per quote request you are showing.
- Subscribe to
heartbeatsso you can tell a healthy-but-quiet connection from a dead one. - A session lives about 120 seconds. Re-subscribe with a new
subscriptionIdto continue quoting after it expires. - Sessions do not survive a disconnect, and a resumed quote is not the same quote. After a reconnect, re-subscribe for a fresh session.
- If the stream is unavailable, fall back to polling
POST /quote.
What can be streamed
Concurrent quote subscriptions are capped per API key. Hitting the cap is not fatal: the subscription is refused with
SUBSCRIPTION_LIMIT, and the socket and its other subscriptions keep running.
Quotes channel
Subscribe
request is a POST /quote body, verbatim:
forceMinimalAllowance: true inside request. The flag applies to EVM and Solana quote revisions. Handle the authorization returned by the newest revision before signing and submitting.
The server confirms with an ack listing your active channels:
ack covers the connection’s channels, not the individual subscription. Treat the ack (and the absence of an error frame carrying your subscriptionId) as admission, and the first quote frame as the stream being live.
Quote
Each revision arrives as aquote frame:
- Revisions arrive in order, and each one fully supersedes the last. Keep only the newest.
- Frames carry no revision number and no session deadline.
quote_expiredis the authoritative end signal, so do not infer expiry from timing. - The first frame is the initial quote. There is no separate snapshot frame.
Quote expired
The session always ends with aquote_expired frame:
Once you receive
quote_expired, the subscriptionId is free to reuse and the quotes in that session can no longer be submitted.
Submitting an order
Submitting is unchanged from the REST flow: sign the newestquote payload and send it to POST /order with that revision’s quoteId. See Market Order for the full signing flow on EVM and Solana.
Submitting consumes the session. The stream closes it and sends quote_expired with reason: "consumed" and the new orderId, so you do not need to unsubscribe afterwards.
Unsubscribing
Stop a single quote session with anunsubscribe message carrying its subscriptionId:
quote_expired with reason: "unsubscribed", then re-acks your remaining channels. Closing the socket ends every quote session on it.
Unsubscribe as soon as a quote is no longer on screen. Sessions are a limited resource, and an abandoned one holds a slot against your per-key limit until its TTL fires.
Example integration
A framework-agnostic reference in about 40 lines:Errors
Errors arrive as a frame you can act on. Errors tied to a subscription carry itssubscriptionId, and the message is human-readable detail, for example which limit was hit:
quote_expired follows:
Ends a live session. Each is followed by
quote_expired with reason: "error":
INVALID_REQUEST and UNAUTHORIZED appear in both categories: rejected before a session opens, no quote_expired follows; rejected after the session opens, the live session ends and quote_expired arrives right after the error frame. Do not key “is a terminal frame coming” off the code alone. Treat an error frame as the failure of the subscribe attempt it answers, and a live session as over only when its quote_expired arrives.
Connection-level codes like UNAUTHORIZED, CONNECTION_LIMIT, and BAD_JSON are covered in Connection.
Orders WebSocket
Stream open orders on the same connection.
Market Order
Sign and submit a quote end to end on EVM and Solana.