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

# Subscribe to real-time updates (SSE)



## OpenAPI

````yaml https://vooi-api-app.fly.dev/swagger/json get /exchange/updates
openapi: 3.1.0
info:
  title: VOOI API
  description: Unified perps API
  version: '1.0'
  contact: {}
servers:
  - url: https://perps-api.vooi.io
security: []
tags: []
paths:
  /exchange/updates:
    get:
      tags:
        - Exchange
      summary: Subscribe to real-time updates (SSE)
      operationId: ExchangeController_subscribeToUpdates
      parameters:
        - name: exchanges
          required: false
          in: query
          schema:
            anyOf:
              - type: string
                enum:
                  - aster
                  - binance
                  - bybit
                  - extended
                  - gate
                  - hyperliquid
                  - lighter
                  - mexc
                  - ondo
                  - robinhood
                description: Supported perpetual exchange
              - type: array
                items:
                  type: string
                  enum:
                    - aster
                    - binance
                    - bybit
                    - extended
                    - gate
                    - hyperliquid
                    - lighter
                    - mexc
                    - ondo
                    - robinhood
                  description: Supported perpetual exchange
        - name: token
          required: false
          in: query
          schema:
            type: string
          description: One-time updates token from POST /exchange/updates-token
      responses:
        '503':
          description: ExchangeApiError
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDTO'
        default:
          description: >-
            Server-Sent Events stream. Events are emitted as named SSE frames
            (event: <name>, id: <counter>, data: <single-line JSON>). The 'id:'
            line is a per-connection counter that starts at 1 on every connect —
            it is not a resumable cursor and the server does not honor
            Last-Event-ID or replay missed events. No SSE keep-alive comments
            are sent.


            Event types:

            - **state**: Full snapshot object { accounts, openOrders, positions,
            exchange }. Fires once on subscribe, only if the server already has
            warm cached state for (user, exchange). Not guaranteed on first
            connect.

            - **accounts**: Array of changed account rows — same shape as GET
            /exchange/accounts items, plus 'exchange'.

            - **order**: Array of changed order rows — same shape as GET
            /exchange/orders items, plus 'exchange'. Cancellations and fills
            arrive with their terminal 'status'.

            - **position**: Array of changed position rows — same shape as GET
            /exchange/positions items, plus 'exchange'. Closed positions are
            emitted with size: '0'.

            - **trade**: Array of new trade rows (your own fills only) — same
            shape as GET /exchange/trades items, plus 'exchange'.

            - **marketPrice**: Array of { marketId, price, fundingRate,
            nextFundingTime, updatedAt, exchange } for symbols the exchange feed
            pushed in this tick. 'fundingRate' is an hourly rate as a decimal on
            every exchange — do not scale it by the market's 'fundingInterval'
            from GET /exchange/markets, which describes only the settlement
            cadence; the charge per settlement is fundingRate × fundingInterval.
            Public, no account context required.

            - **restarting**: { exchange } — the server is reconnecting to the
            upstream exchange. Keep the connection open; more frames follow once
            recovered.

            - **error**: { error, exchange } — the per-exchange synchronizer has
            been torn down. Reconnect with a fresh token to resume.


            Accounts/order/position/trade frames are partial — they carry only
            the rows that changed since the previous frame, not a full
            replacement. Merge into client state by identity.
components:
  schemas:
    ErrorResponseDTO:
      type: object
      properties:
        message:
          type: string
          example: 'Invalid order id: 123'
        statusCode:
          example: 503
          type: number
      required:
        - message
      title: ErrorResponse

````

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