Streaming Quotes

View as Markdown

The 0x Cross-Chain API is in private beta. Request access to start building.

The Cross-Chain API supports streaming of swap quotes using Server-Sent Events (SSE). Quotes are delivered progressively as they’re discovered, so users can act on them immediately.

Why Streaming?

  • Faster first quote — get actionable quotes faster
  • 🔄 Progressive discovery — quotes stream in as they’re found, no blocking waits
  • 🛠️ Immediately executable — every quote includes full transaction details
  • 🎯 Better UX — show users the first good option instead of making them wait

Endpoint

GET /cross-chain/quotes/stream

Streams cross-chain swap quotes as SSE events. Each quote is delivered as a standalone event with everything needed for execution.

Same params as /cross-chain/quotes, except:

  • No sortQuotesBy — quotes stream in discovery order always
  • The maxNumQuotes defaults to 5 for the streaming endpoint (vs. 3 for the non-streaming /quotes endpoint). The stream closes after delivering this many quotes or reaching the timeout, whichever comes first.

After calling the endpoint with proper parameters, you will get back Server-Sent Events with the following message types:

Quote Found

1data: {
2 "event": {
3 "type": "quote",
4 "data": {
5 "quote": { /* full quote object */ },
6 "allowanceTarget": "0x000..."
7 }
8 },
9 "zid": "0xbed7b45844099af94219ba8c"
10}

Stream Done

1data: {
2 "event": {
3 "type": "result",
4 "data": {
5 "liquidityAvailable": true
6 }
7 },
8 "zid": "0xbed7b45844099af94219ba8c"
9}

Error (if stream fails)

1data: {
2 "event": {
3 "type": "error",
4 "data": {
5 "message": "Stream failed due to server error",
6 "code": "STREAM_ERROR"
7 }
8 }
9}

Timeout

The stream has a 30-second server-side timeout. If no quotes are found within this window, a result event with liquidityAvailable: false is sent and the stream closes.

This timeout is not configurable. If you’re getting timeouts:

  • Remove excludedBridges or broaden includedBridges
  • Increase slippageBps
  • Try a more liquid token pair

Reconnection

SSE connections may be dropped by network intermediaries (proxies, load balancers). If the connection closes without a result or error event:

  • The stream is not resumable, just open a new connection with the same parameters
  • Each new connection generates a new zid
  • Add a 1–2 second delay between reconnection attempts

Client Example

1const quoteParams = new URLSearchParams({
2 originChain: '8453', // Base mainnet
3 destinationChain: '42161', // Arbitrum mainnet
4 sellToken: '0x4200000000000000000000000000000000000006', // WETH on Base
5 buyToken: '0xaf88d065e77c8cc2239327c5edb3a432268e5831', // USDC on Arbitrum
6 sellAmount: '1000000000000000000', // Amount of sellToken in base units
7 originAddress: '$USER_TAKER_ADDRESS', // Address that will make the trade
8});
9
10const headers = {
11 '0x-api-key': '[api-key]', // Get your live API key from the 0x Dashboard (https://dashboard.0x.org/apps)
12};
13
14const resp = await fetch('https://api.0x.org/cross-chain/quotes/stream?' + quoteParams.toString(), { headers });
15
16const reader = resp.body.getReader();
17const decoder = new TextDecoder();
18
19while (true) {
20 const { value, done } = await reader.read();
21 if (done) break;
22
23 const chunk = decoder.decode(value, { stream: true });
24
25 chunk.split("\n").forEach(line => {
26 if (line.startsWith("data:")) {
27 const parsed = JSON.parse(line.slice(5).trim());
28 console.log("SSE event:", parsed);
29 }
30 });
31}

You can find a full streaming example with NextJS in 0x-examples.