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

# Stream the best bid and ask

> Streams one market's best bid and ask: a Reset with the current quote, then an Update whenever it changes. A market the venue does not stream returns 422 NotSupported.

> [!NOTE]
>
> **Check support**
>
> Read the venue with [List venues](https://docs.plurex.io/api-reference/platform/venues/list.md). In its `capabilities`
> :
>
> <ul />
>
> See [Venue capabilities](https://docs.plurex.io/capabilities/venue-capabilities.md) and
> [support values](https://docs.plurex.io/capabilities/overview.md#support-values).


## OpenAPI

````yaml api-reference/platform/plurex-platform-api.yaml POST /api/v1/venues/stream/SubscribeToBestQuotes
openapi: 3.2.0
info:
  title: Plurex Platform API
  version: 1.0.0
  description: >-
    Trade across exchanges and brokers through one API, and paper trade any of
    them with the same calls.


    **Venues** are the exchanges where markets trade. Venue operations are
    market data: markets, order books, recent trades, prices, quotes,
    statistics, funding, open interest and candles.


    **Hosts** hold trading accounts and execute orders on a venue's markets, for
    example an exchange's own account service or a broker. Host operations cover
    each host's tradable markets and order rules, and every account action:
    orders, fills, balances, positions, margin, leverage and transactions. A
    venue market tells you what is trading; the matching host market tells you
    what you may order there.


    **Tenants** own trading resources: every account belongs to one tenant. You
    act as your tenant, and your API keys are created under it. Find your tenant
    ID next to your API keys on the DevTools page of the Plurex app. Every
    operation, market data included, needs an API key: send it in the X-API-KEY
    and X-API-SECRET headers.


    **Accounts** are your accounts on hosts. Connect an exchange or broker
    account with its API credentials, or create a **paper** account. A paper
    host simulates a real host against that venue's live order book, so a paper
    account trades through exactly the same host operations and can be switched
    for a real one without code changes.


    **Capabilities.** Hosts and venues differ. Each host and venue lists every
    operation it supports, and each market lists its order types, settings and
    market data. Check these before calling: an unsupported call returns 422
    NotSupported.


    **Requests.** Every operation is a POST with a JSON body (Content-Type
    application/json). Every operation needs both the X-API-KEY and X-API-SECRET
    headers. Unknown fields, unknown enum values and wrong types are rejected
    with 400. Every error has the ErrorEnvelope shape; its code says what went
    wrong.



    **Streams.** Stream operations (paths under /stream/) follow one topic, such
    as an account's orders or a market's order book. Errors are ordinary
    responses before the stream starts; otherwise the 200 response stays open
    and carries one JSON message per line (application/jsonl). Market data
    streams start with a Reset holding the current state, then Updates; a Reset
    can arrive again at any time and replaces everything you hold. Account
    streams send an Event per change and no snapshot: read current state with
    the matching query after the stream opens. A blank line arrives at least
    every 15 seconds while the stream is quiet. The last line is Ended, saying
    why the stream stopped. A stream that falls too far behind, or that ends or
    fails without an Ended line, has lost messages: open it again after a short,
    randomized delay and rebuild from its first message. Open one stream per
    topic; a client using HTTP/2 shares one connection between them.


    **Compatibility.** Enum values, union variants, error codes and fields are
    added over time without a new version. Ignore fields you do not recognise,
    and treat unknown enum values and variants as an unrecognised case instead
    of failing. Removing or renaming any of them would be a breaking change.
servers:
  - url: https://api.plurex.io
security:
  - ApiKey: []
    ApiSecret: []
tags:
  - name: venues
    summary: Market data
    description: Market data from the exchanges where markets trade.
    kind: nav
  - name: venue-markets
    summary: Venues and markets
    description: The venues and their markets, with the market data each market supports.
    parent: venues
    kind: nav
  - name: order-books
    summary: Order books
    description: A market's current bids and asks.
    parent: venues
    kind: nav
  - name: public-trades
    summary: Public trades
    description: A market's recent public trades.
    parent: venues
    kind: nav
  - name: market-observations
    summary: Prices and market statistics
    description: >-
      Current prices, best quotes, statistics, indicative funding and open
      interest, read in batches of instruments.
    parent: venues
    kind: nav
  - name: candles
    summary: Candles
    description: Closed OHLC candles by price kind and interval, newest first.
    parent: venues
    kind: nav
  - name: hosts
    summary: Trading
    description: >-
      Trading on an account: each host's tradable markets and order rules,
      orders, fills, balances, positions, margin, market settings and
      transactions. Paper accounts use these same operations.
    kind: nav
  - name: host-markets
    summary: Hosts and markets
    description: >-
      The hosts and their tradable markets, with each market's order types,
      order rules and settings.
    parent: hosts
    kind: nav
  - name: orders
    summary: Orders
    description: Submit, cancel and read orders.
    parent: hosts
    kind: nav
  - name: fills
    summary: Fills
    description: The account's executions, by order, instrument or across the account.
    parent: hosts
    kind: nav
  - name: portfolio
    summary: Balances and positions
    description: Wallet balances, open positions, margin and per-market account state.
    parent: hosts
    kind: nav
  - name: market-settings
    summary: Leverage and position mode
    description: Read and set the account's leverage and position mode for a market.
    parent: hosts
    kind: nav
  - name: transactions
    summary: Transactions
    description: 'Balance postings: fees, funding payments, deposits and so on.'
    parent: hosts
    kind: nav
  - name: accounts
    summary: Accounts
    description: Connect, list and manage a tenant's exchange, broker and paper accounts.
    kind: nav
  - name: paper
    summary: Paper trading
    description: >-
      Create, fund and draw down paper accounts and set their simulated fees.
      Trade them through the hosts operations like any other account.
    kind: nav
  - name: paper-accounts
    summary: Paper accounts
    description: Create, fund and draw down paper accounts.
    parent: paper
    kind: nav
  - name: paper-fees
    summary: Paper fees
    description: Choose the fee tier a paper account is charged.
    parent: paper
    kind: nav
  - name: optional
    summary: Check capabilities
    description: >-
      Not every host or venue supports this operation; check its capabilities
      first or expect 422 NotSupported.
    kind: badge
  - name: paged
    summary: Paged
    description: Returns pages; follow nextCursor until null.
    kind: badge
  - name: batch
    summary: Batch
    description: Takes a list of identifiers or instruments and handles them in one call.
    kind: badge
  - name: not-repeat-safe
    summary: Not safe to repeat
    description: >-
      Repeating the call repeats its effect. If the outcome is unclear, check
      before retrying. Commands without this badge are safe to repeat.
    kind: badge
paths:
  /api/v1/venues/stream/SubscribeToBestQuotes:
    post:
      tags:
        - market-observations
        - optional
      summary: Stream the best bid and ask
      description: >-
        Streams one market's best bid and ask: a Reset with the current quote,
        then an Update whenever it changes. A market the venue does not stream
        returns 422 NotSupported.
      operationId: venuesSubscribeToBestQuotes
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubscribeToBestQuotesRequest'
      responses:
        '200':
          description: >-
            One message per line: a Reset first, then Updates, until an Ended
            line.
          content:
            application/jsonl:
              itemSchema:
                $ref: '#/components/schemas/BestQuoteStreamMessage'
              examples:
                Stream:
                  summary: A Reset, an Update, a keepalive line and Ended
                  serializedValue: >
                    {"type":"Reset","timestamp":"2026-10-27T09:00:00.120Z","data":{"value":{"bid":{"price":"67250.1","size":"0.42"},"ask":{"price":"67250.2","size":"0.08"}},"observedAt":"2026-10-27T09:00:00.101Z","receivedAt":"2026-10-27T09:00:00.115Z"}}

                    {"type":"Update","timestamp":"2026-10-27T09:00:01.320Z","data":{"value":{"bid":{"price":"67250.1","size":"0.9"},"ask":{"price":"67250.2","size":"0.08"}},"observedAt":"2026-10-27T09:00:01.301Z","receivedAt":"2026-10-27T09:00:01.316Z"}}


                    {"type":"Ended","code":"UpstreamFailure","message":"Upstream
                    stream ended"}
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '404':
          $ref: '#/components/responses/NotFound'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/Rejected'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/UnexpectedError'
        '502':
          $ref: '#/components/responses/UpstreamFailure'
        '503':
          $ref: '#/components/responses/Unavailable'
        '504':
          $ref: '#/components/responses/UpstreamTimeout'
components:
  schemas:
    SubscribeToBestQuotesRequest:
      type: object
      properties:
        venueId:
          type: string
        instrument:
          $ref: '#/components/schemas/Instrument'
      required:
        - venueId
        - instrument
      description: Streams one market's best bid and ask on a venue.
    BestQuoteStreamMessage:
      oneOf:
        - $ref: '#/components/schemas/BestQuoteStreamReset'
        - $ref: '#/components/schemas/BestQuoteStreamUpdate'
        - $ref: '#/components/schemas/StreamEnded'
      discriminator:
        propertyName: type
        mapping:
          Reset: '#/components/schemas/BestQuoteStreamReset'
          Update: '#/components/schemas/BestQuoteStreamUpdate'
          Ended: '#/components/schemas/StreamEnded'
      description: One line of the best bid and ask stream.
    Instrument:
      oneOf:
        - $ref: '#/components/schemas/InstrumentFuture'
        - $ref: '#/components/schemas/InstrumentFutureInv'
        - $ref: '#/components/schemas/InstrumentOption'
        - $ref: '#/components/schemas/InstrumentPerp'
        - $ref: '#/components/schemas/InstrumentPerpInv'
        - $ref: '#/components/schemas/InstrumentSpot'
      discriminator:
        propertyName: type
        mapping:
          Future: '#/components/schemas/InstrumentFuture'
          FutureInv: '#/components/schemas/InstrumentFutureInv'
          Option: '#/components/schemas/InstrumentOption'
          Perp: '#/components/schemas/InstrumentPerp'
          PerpInv: '#/components/schemas/InstrumentPerpInv'
          Spot: '#/components/schemas/InstrumentSpot'
      description: >-
        An instrument, identified by its fields rather than a venue symbol:
        type, base, quote, and expiry, strike and right where they apply. type
        takes the InstrumentType values; unknown types are rejected. Market
        summaries also give its canonical symbol.
    BestQuoteStreamReset:
      title: Reset
      type: object
      properties:
        type:
          type: string
          enum:
            - Reset
          description: Always Reset.
        timestamp:
          type: string
          format: date-time
          description: When Plurex sent the event.
        data:
          $ref: '#/components/schemas/BestQuoteObservation'
          description: The current value.
      required:
        - type
        - timestamp
        - data
      description: >-
        The current best bid and ask, replacing any value you hold. The first
        line of the stream, and sent again whenever the stream has to
        resynchronize.
    BestQuoteStreamUpdate:
      title: Update
      type: object
      properties:
        type:
          type: string
          enum:
            - Update
          description: Always Update.
        timestamp:
          type: string
          format: date-time
          description: When Plurex sent the event.
        data:
          $ref: '#/components/schemas/BestQuoteObservation'
          description: The complete new value.
      required:
        - type
        - timestamp
        - data
      description: >-
        The best bid and ask changed. The value is complete, so a field that is
        now null was cleared.
    StreamEnded:
      title: Ended
      type: object
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
          description: >-
            Why the stream stopped, for example UpstreamFailure when the venue's
            or host's own feed ended.
        message:
          type: string
          description: Readable detail for logs; do not parse it.
        type:
          type: string
          enum:
            - Ended
          description: Always Ended.
      required:
        - type
        - code
        - message
      description: >-
        The last line of every stream: it stopped, and nothing more follows.
        Read current state and open it again.
    ErrorEnvelope:
      type: object
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
      required:
        - code
        - message
      description: >-
        Every error has this shape, at every HTTP status, including unknown
        paths (404 NotFound) and wrong methods (405 MethodNotAllowed). code is
        the specific reason. Each operation describes when to retry and how to
        check the outcome; an error alone does not prove a command had no
        effect.
    InstrumentFuture:
      title: Future
      type: object
      properties:
        base:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        quote:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        expiry:
          type: string
          format: date
          description: Contract expiry date (YYYY-MM-DD).
        type:
          type: string
          enum:
            - Future
      required:
        - type
        - base
        - quote
        - expiry
      description: >-
        A linear dated future, quoted and settled in the quote asset, that
        expires on expiry.
    InstrumentFutureInv:
      title: FutureInv
      type: object
      properties:
        base:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        quote:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        expiry:
          type: string
          format: date
          description: Contract expiry date (YYYY-MM-DD).
        type:
          type: string
          enum:
            - FutureInv
      required:
        - type
        - base
        - quote
        - expiry
      description: >-
        An inverse dated future, quoted in the quote asset and settled in the
        base asset, that expires on expiry.
    InstrumentOption:
      title: Option
      type: object
      properties:
        base:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        quote:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        expiry:
          type: string
          format: date
          description: Contract expiry date (YYYY-MM-DD).
        strike:
          type: string
          pattern: ^(?:0|[1-9][0-9]*)(?:\.[0-9]*[1-9])?$
          description: >-
            Positive strike price in the quote asset, in canonical form so
            identity is exact; a plain decimal with no exponent and no trailing
            fractional zeros (50000, not 50000.0 or 5E4).
        right:
          $ref: '#/components/schemas/OptionRight'
        type:
          type: string
          enum:
            - Option
      required:
        - type
        - base
        - quote
        - expiry
        - strike
        - right
      description: >-
        Option contract. Option markets are not listed or tradable; options
        appear only where a host reports account activity on them.
    InstrumentPerp:
      title: Perp
      type: object
      properties:
        base:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        quote:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        type:
          type: string
          enum:
            - Perp
      required:
        - type
        - base
        - quote
      description: >-
        A linear perpetual swap, with no expiry, quoted and settled in the quote
        asset.
    InstrumentPerpInv:
      title: PerpInv
      type: object
      properties:
        base:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        quote:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        type:
          type: string
          enum:
            - PerpInv
      required:
        - type
        - base
        - quote
      description: >-
        An inverse perpetual swap, with no expiry, quoted in the quote asset and
        settled in the base asset.
    InstrumentSpot:
      title: Spot
      type: object
      properties:
        base:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        quote:
          type: string
          pattern: ^[A-Z0-9.]{1,32}$
        type:
          type: string
          enum:
            - Spot
      required:
        - type
        - base
        - quote
      description: 'A spot pair: buying or selling the base asset for the quote asset.'
    BestQuoteObservation:
      type: object
      properties:
        value:
          $ref: '#/components/schemas/BestQuote'
        observedAt:
          type:
            - string
            - 'null'
          format: date-time
          description: Venue time of the value; null when the venue gives none.
        receivedAt:
          type: string
          format: date-time
          description: When Plurex received the value.
      required:
        - value
        - observedAt
        - receivedAt
      description: >-
        The best bid and ask of the streamed market, with when the venue
        reported it and when Plurex received it.
    ErrorCode:
      type: string
      enum:
        - InvalidRequest
        - Unauthenticated
        - Forbidden
        - AccountNotFound
        - OrderNotFound
        - NotFound
        - MethodNotAllowed
        - DuplicateClientOrderId
        - OrderAlreadyClosed
        - Conflict
        - UnsupportedMediaType
        - InsufficientFunds
        - InvalidProviderCredentials
        - AccountLimit
        - NotSupported
        - Rejected
        - RateLimited
        - UnexpectedError
        - CancelAllFailed
        - UpstreamFailure
        - Unavailable
        - UpstreamTimeout
      description: >-
        Stable error reason. The HTTP status for each code is fixed:
        InvalidRequest (400): Malformed JSON, wrong types, unknown fields or
        enum values, or invalid values.; Unauthenticated (401): Missing or
        invalid API key headers.; Forbidden (403): Authenticated, but without
        access to the account or operation.; AccountNotFound (404): The
        accountId does not exist.; OrderNotFound (404): The account exists, but
        the order identifier does not.; NotFound (404): Unknown path, host or
        venue.; MethodNotAllowed (405): The path exists but only accepts POST.;
        DuplicateClientOrderId (409): An order with this clientOrderId already
        exists.; OrderAlreadyClosed (409): The order is already filled,
        cancelled or rejected.; Conflict (409): A unique value (for example an
        account name) is already used.; UnsupportedMediaType (415): The request
        is not Content-Type application/json.; InsufficientFunds (422): The
        account cannot fund the order or withdrawal.; InvalidProviderCredentials
        (422): The provider rejected the account credentials.; AccountLimit
        (422): An account or subscription limit was reached.; NotSupported
        (422): The host does not support this operation, variant or instrument.;
        Rejected (422): The host or validation rejected the command.;
        RateLimited (429): The provider rate limited the request.;
        UnexpectedError (500): Unexpected server failure.; CancelAllFailed
        (502): At least one sub-cancel failed; reconcile with ListOpenOrders.;
        UpstreamFailure (502): The provider failed or returned an unusable
        response.; Unavailable (503): The service or provider is temporarily
        unavailable.; UpstreamTimeout (504): The provider did not respond in
        time. New codes may be added; treat an unknown code by its HTTP status.
    OptionRight:
      type: string
      enum:
        - Call
        - Put
      description: >-
        Whether an option gives the right to buy (Call) or to sell (Put) the
        underlying at the strike.
    BestQuote:
      type: object
      properties:
        bid:
          anyOf:
            - $ref: '#/components/schemas/QuoteLevel'
            - type: 'null'
          description: Null when the venue reports no bid.
        ask:
          anyOf:
            - $ref: '#/components/schemas/QuoteLevel'
            - type: 'null'
          description: Null when the venue reports no ask.
      required:
        - bid
        - ask
      description: The best bid and best ask of a market.
    QuoteLevel:
      type: object
      properties:
        price:
          $ref: '#/components/schemas/Decimal'
        size:
          anyOf:
            - $ref: '#/components/schemas/Decimal'
            - type: 'null'
          description: >-
            Native contract units; null when the market does not report sizes
            (BestQuoteSpec.supportsSizes).
      required:
        - price
        - size
      description: >-
        The price and, when reported, the size at the top of one side of the
        book.
    Decimal:
      type: string
      pattern: ^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?$
      description: >-
        An exact decimal number encoded as a string. No binary floating-point
        rounding.
  responses:
    BadRequest:
      description: 400 BadRequest; code is InvalidRequest.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            InvalidRequest:
              summary: >-
                The body is malformed, has unknown fields or wrong types, or a
                value is invalid
              value:
                code: InvalidRequest
                message: Invalid cursor
    Unauthenticated:
      description: 401 Unauthenticated; code is Unauthenticated.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            Unauthenticated:
              summary: The API key headers are missing or invalid
              value:
                code: Unauthenticated
                message: Unauthorized
    NotFound:
      description: 404 NotFound; code is AccountNotFound, OrderNotFound or NotFound.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            AccountNotFound:
              summary: The accountId does not exist
              value:
                code: AccountNotFound
                message: 'Account not found: acc_123'
            OrderNotFound:
              summary: The account exists, but the order identifier does not
              value:
                code: OrderNotFound
                message: 'Order not found: ord_456'
            NotFound:
              summary: Unknown path, host or venue
              value:
                code: NotFound
                message: Not Found
    UnsupportedMediaType:
      description: 415 UnsupportedMediaType; code is UnsupportedMediaType.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            UnsupportedMediaType:
              summary: The request is not Content-Type application/json
              value:
                code: UnsupportedMediaType
                message: Content type text/plain is not supported
    Rejected:
      description: >-
        422 Rejected; code is InsufficientFunds, InvalidProviderCredentials,
        AccountLimit, NotSupported or Rejected.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            InsufficientFunds:
              summary: The account cannot fund the order or withdrawal
              value:
                code: InsufficientFunds
                message: Insufficient Funds
            InvalidProviderCredentials:
              summary: The provider rejected the account credentials
              value:
                code: InvalidProviderCredentials
                message: Unprocessable Entity
            AccountLimit:
              summary: An account or subscription limit was reached
              value:
                code: AccountLimit
                message: Subscription limit reached
            NotSupported:
              summary: The host does not support this operation, variant or instrument
              value:
                code: NotSupported
                message: Unprocessable Entity
            Rejected:
              summary: The host or validation rejected the command
              value:
                code: Rejected
                message: Order price is not a multiple of the price increment
    RateLimited:
      description: 429 RateLimited; code is RateLimited.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            RateLimited:
              summary: The provider rate limited the request
              value:
                code: RateLimited
                message: Provider rate limited
    UnexpectedError:
      description: 500 UnexpectedError; code is UnexpectedError.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            UnexpectedError:
              summary: Unexpected server failure
              value:
                code: UnexpectedError
                message: Internal Server Error
    UpstreamFailure:
      description: 502 UpstreamFailure; code is UpstreamFailure or CancelAllFailed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            UpstreamFailure:
              summary: The host or venue failed or returned something unreadable
              value:
                code: UpstreamFailure
                message: Bad Gateway
            CancelAllFailed:
              summary: At least one sub-cancel failed; reconcile with ListOpenOrders
              value:
                code: CancelAllFailed
                message: Bad Gateway
    Unavailable:
      description: 503 Unavailable; code is Unavailable.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            Unavailable:
              summary: The service or provider is temporarily unavailable
              value:
                code: Unavailable
                message: Service Unavailable
    UpstreamTimeout:
      description: 504 UpstreamTimeout; code is UpstreamTimeout.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            UpstreamTimeout:
              summary: The provider did not respond in time
              value:
                code: UpstreamTimeout
                message: Gateway Timeout
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-KEY
    ApiSecret:
      type: apiKey
      in: header
      name: X-API-SECRET

````

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