> ## Documentation Index
> Fetch the complete documentation index at: https://docs.totalis.trade/llms.txt
> Use this file to discover all available pages before exploring further.

# Stream quote updates

> Subscribe to real-time best-quote updates for a quote request via Server-Sent Events.

Open a Server-Sent Events (SSE) stream for one quote request. You receive the current best quote each time market makers submit, update, or withdraw quotes.

## Authentication

Send your API key in the `X-API-Key` header. The key needs the `positions:read` scope.

```
X-API-Key: <your-api-key>
```

A Privy JWT (`Authorization: Bearer <jwt>`) is also accepted. See [Authentication](/solana/authentication).

## Path parameters

<ParamField path="id" type="string" required>
  The quote request ID (UUID).
</ParamField>

## SSE event types

### `best_quote`

Sent whenever the quote book changes: a quote is submitted, updated, withdrawn, or expires. `book_seq` increments monotonically, so a gap means you missed an update.

```json theme={null}
{
  "book_seq": 5,
  "version": 3,
  "request_hash": "sha256:9f86d08...",
  "best_quote": {
    "id": "b2c3d4e5-6789-0abc-def1-234567890abc",
    "payout_odds": 4.0,
    "user_cost": 24.75,
    "total_payout": 99,
    "mm_cost": 74.25,
    "valid_until": "2026-06-01T18:45:45.000Z",
    "market_maker_id": "did:privy:cm3mm..."
  }
}
```

When no quotes are active, `best_quote` is `null`:

```json theme={null}
{
  "book_seq": 6,
  "version": 3,
  "request_hash": "sha256:9f86d08...",
  "best_quote": null
}
```

### `status`

Sent when the quote request leaves `active` (committed, cancelled, or expired). `committed_rfq_id` is the created RFQ id when `status` is `committed`, and `null` otherwise.

```json theme={null}
{
  "status": "committed",
  "committed_rfq_id": "c3d4e5f6-7890-abcd-ef12-34567890abcd"
}
```

Immediately after `status`, the stream sends one **terminal event** for the outcome (`committed`, `cancelled`, or `expired`) and closes. Listen for either `status` or the terminal event.

### `committed`

The quote request was committed into an [RFQ](/solana/glossary#the-noun-stack). Follow the trade through confirmation and settlement on the [WebSocket](/solana/guides/websocket) `rfq:{rfq_id}` channel.

```json theme={null}
{
  "quote_request_id": "1a6d1f06-9d4f-47cb-994b-3bdfbbef7e40",
  "rfq_id": "c3d4e5f6-7890-abcd-ef12-34567890abcd"
}
```

### `cancelled`

You cancelled the quote request with [Cancel](/solana/api-reference/quote-service/cancel).

```json theme={null}
{
  "quote_request_id": "1a6d1f06-9d4f-47cb-994b-3bdfbbef7e40"
}
```

### `expired`

The quote request reached its `expires_at` without being committed.

```json theme={null}
{
  "quote_request_id": "1a6d1f06-9d4f-47cb-994b-3bdfbbef7e40"
}
```

## Integration guide

1. Open the stream after you create or update a quote request.
2. On each `best_quote` event, update the payout odds you display. Store `book_seq` and the best quote `id`.
3. To commit, send `expected_version`, `displayed_quote_id`, `displayed_quote_book_seq`, and `min_payout_odds_seen` to [Commit](/solana/api-reference/quote-service/commit).
4. On a terminal event, close the stream and handle the outcome. On a commit, read the RFQ id from `committed_rfq_id` (`status` event) or `rfq_id` (`committed` event). Follow the trade on the [WebSocket](/solana/guides/websocket) `rfq:{rfq_id}` channel.

## Errors

| Status | Code | Description |
| - | - | - |
| 401 | `UNAUTHORIZED` | Missing or invalid API key. |
| 403 | `FORBIDDEN` | You do not own this quote request, or the credential does not start with `api_` (`details.reason: "wrong_api_key_type"`). |
| 404 | `NOT_FOUND` | Quote request not found. |

<RequestExample>
  ```bash curl theme={null}
  curl -N https://api.totalis.trade/v1/quote-requests/1a6d1f06-9d4f-47cb-994b-3bdfbbef7e40/stream \
    -H "X-API-Key: $TOTALIS_API_KEY" \
    -H "Accept: text/event-stream"
  ```

  ```javascript JavaScript theme={null}
  // Native EventSource cannot send an X-API-Key header, so read the SSE stream
  // with fetch instead (works in browsers and Node 18+).
  async function streamQuotes(id, apiKey) {
    const res = await fetch(
      `https://api.totalis.trade/v1/quote-requests/${id}/stream`,
      { headers: { 'X-API-Key': apiKey, Accept: 'text/event-stream' } }
    );

    const reader = res.body.getReader();
    const decoder = new TextDecoder();
    let buffer = '';

    while (true) {
      const { done, value } = await reader.read();
      if (done) return;
      buffer += decoder.decode(value, { stream: true });

      let sep;
      while ((sep = buffer.indexOf('\n\n')) !== -1) {
        const frame = buffer.slice(0, sep);
        buffer = buffer.slice(sep + 2);
        const event = frame.match(/^event: (.+)$/m)?.[1];
        const data = frame.match(/^data: (.+)$/m)?.[1];
        if (!event || !data) continue;
        const payload = JSON.parse(data);

        if (event === 'best_quote') {
          console.log('Best quote:', payload.best_quote, 'book_seq:', payload.book_seq);
        } else if (event === 'committed') {
          console.log('RFQ created:', payload.rfq_id);
          return; // the stream closes after a terminal event
        } else if (event === 'cancelled' || event === 'expired') {
          console.log('Terminal:', event);
          return;
        }
      }
    }
  }
  ```

  ```python Python theme={null}
  import json
  import os
  import requests

  quote_request_id = '1a6d1f06-9d4f-47cb-994b-3bdfbbef7e40'
  url = f'https://api.totalis.trade/v1/quote-requests/{quote_request_id}/stream'
  headers = {
      'X-API-Key': os.environ['TOTALIS_API_KEY'],
      'Accept': 'text/event-stream',
  }

  event_type = None
  with requests.get(url, headers=headers, stream=True) as resp:
      for line in resp.iter_lines(decode_unicode=True):
          if line.startswith('event: '):
              event_type = line[7:]
          elif line.startswith('data: '):
              payload = json.loads(line[6:])
              if event_type == 'best_quote':
                  print('Best quote:', payload['best_quote'])
              elif event_type in ('committed', 'cancelled', 'expired'):
                  print(f'Terminal: {event_type}', payload)
                  break
              event_type = None
  ```
</RequestExample>

<ResponseExample>
  ```text SSE stream theme={null}
  event: best_quote
  data: {"book_seq":1,"version":1,"request_hash":"sha256:9f86d08...","best_quote":{"id":"b2c3d4e5-6789-0abc-def1-234567890abc","payout_odds":4.0,"user_cost":24.75,"total_payout":99,"mm_cost":74.25,"valid_until":"2026-06-01T18:45:45.000Z","market_maker_id":"did:privy:cm3mm..."}}

  event: best_quote
  data: {"book_seq":2,"version":1,"request_hash":"sha256:9f86d08...","best_quote":{"id":"e5f6a7b8-9012-cdef-3456-7890abcdef12","payout_odds":4.4,"user_cost":24.75,"total_payout":108.9,"mm_cost":84.15,"valid_until":"2026-06-01T18:45:50.000Z","market_maker_id":"did:privy:cm9mm..."}}

  event: status
  data: {"status":"committed","committed_rfq_id":"c3d4e5f6-7890-abcd-ef12-34567890abcd"}

  event: committed
  data: {"quote_request_id":"1a6d1f06-9d4f-47cb-994b-3bdfbbef7e40","rfq_id":"c3d4e5f6-7890-abcd-ef12-34567890abcd"}
  ```
</ResponseExample>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.