openapi: "3.0.2"
info:
  title: Bitvavo Request for Quote API
  version: "2.13.0"
  description: |
    Manage Request for Quote (RFQ) trading and reporting for your account.

servers:
  - url: https://api.bitvavo.com/v2/rfq

security:
  - Bitvavo-Access-Key: []
    Bitvavo-Access-Timestamp: []
    Bitvavo-Access-Signature: []
    Bitvavo-Access-Window: []

paths:
  /trades:
    get:
      summary: Get trade history
      description: |
        Returns the specified number of past RFQ trades for your account and a time period of up to 24 hours.
        
        The returned trades are sorted by their `timestamp` in a descending order, from the latest to the earliest.

        :::info
        This is a *private* endpoint. To send requests, you need to [authenticate](/docs/rfq-api/introduction/). Your API key must have the **View access** permission.
        :::

        :::tip
        To get specific trades, use the `start`, `end`, and `tradeId` parameters.
        :::

        **Rate limit weight points**: **5**

      parameters:
        - name: limit
          in: query
          required: false
          description: |
            The maximum number of trades to return, from latest to earliest.
          schema:
            type: integer
            default: 500
            minimum: 1
            maximum: 1000

        - name: start
          in: query
          required: false
          description: |
            The Unix timestamp starting from which to return trades. If used, you must also specify the `end` parameter.
            <br/>
            > Can only return trades for a period of up to 24 hours.
          schema:
            type: integer
            format: unix-timestamp in milliseconds
            minimum: 0
          example: 1700000000000

        - name: end
          in: query
          required: false
          description: |
            The Unix timestamp up to which to return trades. If used, you must also specify the `start` parameter.
            <br/>
            > Cannot be more than 24 hours after the `start` parameter. Can only return trades for a period of up to 24 hours.
          schema:
            type: integer
            format: unix-timestamp in milliseconds
            minimum: 0
          example: 1700003600000

        - name: tradeId
          in: query
          required: false
          description: |
            Returns the specified trade.
            <br/>
            > If provided, takes precedence over other parameters.
          schema:
            type: string

        - name: base
          in: query
          required: false
          description: |
            Returns trades for the specified base asset.
          schema:
            type: string
            example: BTC

        - name: quote
          in: query
          required: false
          description: |
            Returns trades for the specified quote asset.
          schema:
            type: string
            example: EUR

      responses:
        '200':
          description: The request was successful.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/RfqTrade"
        'Errors':
          description: For error codes, see [Handle errors](/docs/errors).

  /config/markets:
    get:
      summary: Get RFQ markets
      description: |
        Returns the configured RFQ markets, one entry per market with its full quote structure.

        `PRICE_GUARANTEE_CONVERT` entries are overrides per pair: `enabled: false` disables that convert pair; `enabled: true` overrides the quote structure for that pair.

        :::info
        This is a *private* endpoint. To send requests, you need to [authenticate](/docs/rfq-api/introduction/). Your API key must have the **View access** permission.
        :::

        **Rate limit weight points**: **1**

      parameters:
        - name: rfqType
          in: query
          required: false
          description: |
            Returns markets for the specified type of RFQ. If not specified, returns markets for all types.

            Possible values:

            - `STABLECOIN_PARITY` — EUR/EURC conversion at a 1:1 rate.
            - `PRICE_GUARANTEE` — the standard Price Guarantee RFQ for spot markets.
            - `PRICE_GUARANTEE_UK` — the Price Guarantee RFQ variant for United Kingdom customers. Markets are quoted in `GBP`.
            - `PRICE_GUARANTEE_CONVERT` — the Price Guarantee RFQ variant used for asset-to-asset conversions (the Convert product).
          schema:
            type: string
            example: PRICE_GUARANTEE

        - name: enabled
          in: query
          required: false
          description: |
            If `true`, returns only tradeable markets. If `false`, returns only non-tradeable markets. If not specified, returns all markets.
          schema:
            type: boolean

        - name: market
          in: query
          required: false
          description: |
            Returns the specified market.
          schema:
            type: string
            example: BTC-EUR

      responses:
        '200':
          description: The request was successful.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/RfqMarket"
        'Errors':
          description: For error codes, see [Handle errors](/docs/errors).

  /admin/{rfqType}/status:
    get:
      summary: Get RFQ status
      description: |
        Returns whether the specified type of RFQ trade is enabled for your account. 


        :::info
        This is a *private* endpoint. To send requests, you need to [authenticate](/docs/rfq-api/introduction/). Your API key must have the **View access** permission.
        :::

        **Rate limit weight points**: **1**

      parameters:
        - $ref: "#/components/parameters/RfqTypeParam"

      responses:
        '200':
          description: The request was successful.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RfqStatusResponse"
        'Errors':
          description: For error codes, see [Handle errors](/docs/errors).

    put:
      summary: Update RFQ status
      description: |
        Enables or disables the specified type of RFQ trade for your account.

        :::info
        This is a *private* endpoint. To send requests, you need to [authenticate](/docs/rfq-api/introduction/). Your API key must have the **Trade digital assets** permission.
        :::

        **Rate limit weight points**: **1**

      parameters:
        - $ref: "#/components/parameters/RfqTypeParam"

      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RfqStatusUpdateRequest"

      responses:
        '200':
          description: The request was successful.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RfqStatusResponse"
        'Errors':
          description: For error codes, see [Handle errors](/docs/errors).

components:
  securitySchemes:
    Bitvavo-Access-Key:
      description: |
        Your 64-character API key with the required permissions.
      name: Bitvavo-Access-Key
      type: apiKey
      in: header

    Bitvavo-Access-Timestamp:
      description: |
        A Unix timestamp in milliseconds indicating when the request was made.
        Example: 1700000000123
      name: Bitvavo-Access-Timestamp
      type: apiKey
      in: header

    Bitvavo-Access-Signature:
      description: |
        An HMAC-SHA256 hex-encoded string of the timestamp,
        HTTP method, path, and parameters used to make the request.
      name: Bitvavo-Access-Signature
      type: apiKey
      in: header

    Bitvavo-Access-Window:
      description: |
        The execution timeout in milliseconds after Bitvavo-Access-Timestamp.
        Default: 10000. Maximum: 60000.
      name: Bitvavo-Access-Window
      type: apiKey
      in: header

  parameters:
    RfqTypeParam:
      name: rfqType
      in: path
      required: true
      description: The type of RFQ trade.
      schema:
        type: string
        enum: [StablecoinParity]

  schemas:
    RfqType:
      type: string
      enum:
        - STABLECOIN_PARITY
        - PRICE_GUARANTEE
        - PRICE_GUARANTEE_UK
        - PRICE_GUARANTEE_CONVERT
      description: |
        The type of the RFQ. Possible values:

        - `STABLECOIN_PARITY` — EUR/EURC conversion at a 1:1 rate.
        - `PRICE_GUARANTEE` — the standard Price Guarantee RFQ for spot markets.
        - `PRICE_GUARANTEE_UK` — the Price Guarantee RFQ variant for United Kingdom customers. Markets are quoted in `GBP`.
        - `PRICE_GUARANTEE_CONVERT` — the Price Guarantee RFQ variant used for asset-to-asset conversions (the Convert product).

    RfqMarket:
      type: object
      description: The configuration of an RFQ market, including the structure that a quote must conform to.
      additionalProperties: false
      required:
        - market
        - base
        - quote
        - rfqType
        - enabled
        - tickSize
        - quantityDecimals
        - notionalDecimals
      properties:
        market:
          type: string
          description: The market in `BASE-QUOTE` format.
          example: BTC-EUR
        base:
          type: string
          description: The base asset of the market.
          example: BTC
        quote:
          type: string
          description: The quote asset of the market.
          example: EUR
        rfqType:
          $ref: "#/components/schemas/RfqType"
        enabled:
          type: boolean
          description: Indicates whether the market is tradeable.
          example: true
        tickSize:
          type: string
          description: |
            The minimum price increment of the market. A quoted price must be a multiple of this value.
            <br/>
            > Matches the `tickSize` value returned by [Get markets](/docs/rest-api/get-markets/).
          example: "0.01"
        quantityDecimals:
          type: integer
          format: int32
          description: The maximum number of decimal places for the base-asset amount.
          example: 8
        notionalDecimals:
          type: integer
          format: int32
          description: |
            The maximum number of decimal places for the notional amount. If required, the notional is rounded to this many decimal places. Used to validate the quantity if it is requested in quote-asset terms.
          example: 2
        minOrderInBaseAsset:
          type: string
          description: |
            The minimum amount of base currency for an order in the specified market. `0` means no minimum.
          example: "0.0001"
        maxOrderInBaseAsset:
          type: string
          description: |
            The maximum amount of base currency for an order in the specified market. `0` means no maximum.
          example: "50"
        minOrderInQuoteAsset:
          type: string
          description: |
            The minimum amount of quote currency for an order in the specified market. `0` means no minimum.
          example: "5"
        maxOrderInQuoteAsset:
          type: string
          description: |
            The maximum amount of quote currency for an order in the specified market. `0` means no maximum.
          example: "500000"
        maxPriceDeviationBps:
          type: string
          nullable: true
          description: |
            The maximum allowed deviation of a quoted price from the reference price, in basis points. Returned as a decimal string. Quotes outside this band are rejected. `null` means no limit.
          example: "50"

    RfqTrade:
      type: object
      additionalProperties: false
      properties:
        tradeId:
          type: integer
          format: int64
          description: The unique identifier of the trade.
        accountId:
          type: string
          description: The unique identifier of your account.
        rfqId:
          type: string
          description: The unique identifier of the RFQ session.
          example: "32"
        quoteId:
          type: integer
          format: int64
          description: The internal identifier of the quote, assigned by Bitvavo. Used for tracing and reporting.
          example: 90011223344
        clientQuoteId:
          type: string
          description: A unique identifier (UUID) that you assign to the quote. Used for tracing only.
          example: "5d8f2ab0-09d0-4f11-8b4a-3f8ea4c4a5cb"
        timestamp:
          type: integer
          format: unix-timestamp in milliseconds
          description: The Unix timestamp in milliseconds when the trade was executed.
          example: 1700000000000
        amount:
          type: string
          description: The amount of the base currency.
          example: "0.1"
        rfqType:
          type: string          
          example: "StablecoinParity"
          description: |
            The type of RFQ trade.
        base:
          type: string
          description: The base asset of the trade.
          example: "EUR"
        quote:
          type: string
          description: The quote asset of the trade.
          example: "EURC"
        price:
          type: string
          description: The price of 1 unit of base currency in the amount of quote currency at the time of the trade.
          example: "34243"
        side:
          type: string
          enum: [buy, sell]
          description: Indicates whether the taker is buying or selling.
        taker:
          type: boolean
          description: Indicates whether you are the taker for the trade.
        fee:
          type: string
          description: The fee for this trade.
          example: "0.02"
        feeAsset:
          type: string
          description: The currency in which the fee was charged.
          example: "EUR"
        quoteAmount:
          type: string
          description: The gross amount of the settled quote asset after it was rounded, before fees.
          example: "100.00000000"
        operatorId:
          type: integer
          format: int64
          description: Your identifier for the trader or the bot within your account that made the request.
          example: 543462

    RfqStatusUpdateRequest:
      type: object
      additionalProperties: false
      required:
        - rfqEnabled
      properties:
        rfqEnabled:
          type: boolean
          description: Indicates whether RFQ is enabled.
        reason:
          type: string
          description: Optional description of an audit or incident.

    RfqStatusResponse:
      type: object
      additionalProperties: false
      properties:
        rfqType:
          type: string          
          example: "StablecoinParity"
          description: |
            The type of RFQ trade.
        rfqEnabled:
          type: boolean
          description: Indicates whether RFQ is enabled.

    Error:
      type: object
      additionalProperties: true
