openapi: 3.0.3
info:
  title: Balancing Services REST API
  version: 2.4.0
  description: REST API for balancing services data
  contact:
    name: Balancing Services Team

servers:
  - url: https://api.balancing.services/v2
    description: Production API server

security:
  - BearerAuth: []

paths:
  /imbalance/prices:
    get:
      summary: Get imbalance prices for an area
      description: Returns imbalance prices for the specified area within the given time period. Prices are in the specified currency per MWh. Supports cursor-based pagination for large result sets.
      operationId: getImbalancePrices
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImbalancePricesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /imbalance/prices/forecast:
    get:
      summary: Get imbalance price forecasts for an area
      description: |
        **Experimental** - This endpoint is under active development and may change without notice.

        Returns imbalance price forecasts for the specified area within the given time period. Each
        forecast is a predictive distribution: level/price pairs in `quantiles`, ascending by level.
        An area without forecast coverage returns an empty result rather than an error. Supports
        cursor-based pagination for large result sets.
      operationId: getImbalancePriceForecasts
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImbalancePriceForecastsResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /imbalance/prices/history:
    get:
      summary: Get the revision history of the imbalance prices for an area
      description: |
        **Experimental** - This endpoint is under active development and may change without notice.

        Returns how the imbalance prices on `/imbalance/prices` reached their current values: the
        sequence of values held for a period, each stamped with the `observedAt` it was recorded at.
        The response is the `/imbalance/prices` shape with `observedAt` added to each entry of
        `prices`, which carries the revision entries, ascending by `observedAt`.
      operationId: getImbalancePriceHistory
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImbalancePriceHistoryResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /imbalance/total-volumes:
    get:
      summary: Get total imbalance volumes for an area
      description: Returns total aggregated imbalance volumes for the specified area within the given time period. Volumes are expressed as average power in MW. Supports cursor-based pagination for large result sets.
      operationId: getImbalanceTotalVolumes
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImbalanceTotalVolumesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /imbalance/total-volumes/current:
    get:
      summary: Get current (provisional) total imbalance volumes for an area
      description: |
        **Experimental** - This endpoint is under active development and may change without notice.

        Returns the current balancing state (ENTSO-E GL EB article 12.3.A): the open area control error at
        1-minute resolution, published roughly 25 minutes behind real time. This is the real-time preview of
        the total imbalance volume — values are provisional and are superseded by the settled volumes on
        /imbalance/total-volumes once those publish. Data is retained for roughly 90 days. Volumes are
        expressed as average power in MW. Supports cursor-based pagination for large result sets.
      operationId: getCurrentImbalanceTotalVolumes
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 120, max 1440)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1440
            default: 120
            example: 120
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImbalanceTotalVolumesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /imbalance/total-volumes/history:
    get:
      summary: Get the revision history of the total imbalance volumes for an area
      description: |
        **Experimental** - This endpoint is under active development and may change without notice.

        Returns how the total imbalance volumes on `/imbalance/total-volumes` reached their current
        values: the sequence of values held for a period, each stamped with the `observedAt` it was
        recorded at. The response is the `/imbalance/total-volumes` shape with `observedAt` added to
        each entry of `volumes`, which carries the revision entries, each period's ascending by
        `observedAt` and the periods themselves in page order. A period appears once per change of
        the value served for it — its direction or its magnitude — except for entries sharing an
        `observedAt`, which are all returned because no order is recorded within an instant.
      operationId: getImbalanceTotalVolumeHistory
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImbalanceTotalVolumeHistoryResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/activated-volumes:
    get:
      summary: Get activated balancing energy volumes
      description: Returns activated balancing energy volumes for the specified area within the given time period. Volumes are expressed as (average) power in MW. Supports cursor-based pagination for large result sets.
      operationId: getBalancingEnergyActivatedVolumes
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingEnergyVolumesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/activated-volumes/history:
    get:
      summary: Get the revision history of the activated balancing energy volumes for an area
      description: |
        **Experimental** - This endpoint is under active development and may change without notice.

        Returns how the activated balancing energy volumes on `/balancing/energy/activated-volumes`
        reached their current values: the sequence of values held for a period, each stamped with the
        `observedAt` it was recorded at. The response is the `/balancing/energy/activated-volumes`
        shape with `observedAt` added to each entry of `volumes`, which carries the revision entries,
        ascending by `observedAt`.
      operationId: getBalancingEnergyActivatedVolumeHistory
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingEnergyActivatedVolumeHistoryResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/offered-volumes:
    get:
      summary: Get offered balancing energy volumes
      description: Returns offered balancing energy volumes for the specified area within the given time period. Volumes are expressed as (average) power in MW. Supports cursor-based pagination for large result sets.
      operationId: getBalancingEnergyOfferedVolumes
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingEnergyVolumesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/offered-volumes/history:
    get:
      summary: Get the revision history of the offered balancing energy volumes for an area
      description: |
        **Experimental** - This endpoint is under active development and may change without notice.

        Returns how the offered balancing energy volumes on `/balancing/energy/offered-volumes`
        reached their current values: the sequence of values held for a period, each stamped with the
        `observedAt` it was recorded at. The response is the `/balancing/energy/offered-volumes`
        shape with `observedAt` added to each entry of `volumes`, which carries the revision entries,
        ascending by `observedAt`.
      operationId: getBalancingEnergyOfferedVolumeHistory
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingEnergyOfferedVolumeHistoryResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/prices:
    get:
      summary: Get balancing energy prices
      description: Returns balancing energy prices for the specified area and reserve type within the given time period. Prices are in the specified currency per MWh. Supports cursor-based pagination for large result sets.
      operationId: getBalancingEnergyPrices
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingEnergyPricesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/prices/history:
    get:
      summary: Get the revision history of the balancing energy prices for an area
      description: |
        **Experimental** - This endpoint is under active development and may change without notice.

        Returns how the balancing energy prices on `/balancing/energy/prices` reached their current
        values: the sequence of values held for a period, each stamped with the `observedAt` it was
        recorded at. The response is the `/balancing/energy/prices` shape with `observedAt` added to
        each entry of `prices`, which carries the revision entries, ascending by `observedAt`.
      operationId: getBalancingEnergyPriceHistory
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingEnergyPriceHistoryResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/bids:
    get:
      summary: Get balancing energy bids
      description: |
        Returns balancing energy bids for the specified area within the given time period. Prices are in
        the specified currency per MWh.

        Bids are grouped by their shared dimensions (area, reserve type, direction, currency,
        standard-product flag), and inside each group by delivery period: each entry of `periods` states
        the period once and carries that period's bids. Period entries ascend by period start within
        their group.

        Supports cursor-based pagination for large result sets; `limit` counts individual bids, not
        groups or period entries. Groups and period entries are assembled per page: when `hasMore` is
        true the last period entry may continue on the next page, so merge entries on their group's
        dimensions plus the period when accumulating pages. Bids within a period entry are returned in no
        guaranteed order — sort by price client-side if you need the merit order. When polling with
        `updated-since`, change is tracked per stored bid set rather than per bid: a changed set is
        re-delivered with its unchanged bids included, so the period entries of a poll are not
        necessarily contiguous. A period entry may span more than one tracked set, and a set that
        changes again mid-drain is deferred to the next poll, so a filtered response is not guaranteed
        to carry a period's complete bid set — re-fetch without `updated-since` to reconcile
        withdrawals.
      operationId: getBalancingEnergyBids
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingEnergyBidsResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/demand:
    get:
      summary: Get balancing energy demand
      description: |
        **EXPERIMENTAL**: Returns balancing energy demand for the specified area within the given time period,
        i.e. the balancing energy requested by the TSO. Demand is expressed as (average) power in MW.
        Supports cursor-based pagination for large result sets.

        This endpoint is experimental and may be changed or removed without a deprecation period.
      operationId: getBalancingEnergyDemand
      x-experimental: true
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingEnergyVolumesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/satisfied-demand:
    get:
      summary: Get satisfied balancing energy demand
      description: |
        **EXPERIMENTAL**: Returns satisfied balancing energy demand for the specified area within the given time period,
        i.e. the part of the TSO's balancing energy demand that was satisfied. Satisfied demand is expressed as (average) power in MW.
        Supports cursor-based pagination for large result sets.

        This endpoint is experimental and may be changed or removed without a deprecation period.
      operationId: getBalancingEnergySatisfiedDemand
      x-experimental: true
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingEnergyVolumesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/capacity/bids:
    get:
      summary: Get balancing capacity bids
      description: |
        Returns balancing capacity bids for the specified area within the given time period. Prices are
        in the specified currency per MW per hour.

        Bids are grouped by their shared dimensions (area, reserve type, direction, currency), and inside
        each group by delivery period: each entry of `periods` states the period once and carries that
        period's bids. Period entries ascend by period start within their group. Each bid carries the
        procurement it was submitted to (`procurement.procuredAt`) — a single period entry can mix bids
        from multiple procurement rounds.

        Supports cursor-based pagination for large result sets; `limit` counts individual bids, not
        groups or period entries. Groups and period entries are assembled per page: when `hasMore` is
        true the last period entry may continue on the next page, so merge entries on their group's
        dimensions plus the period when accumulating pages. Bids within a period entry are returned in no
        guaranteed order — sort by price client-side if you need the merit order. When polling with
        `updated-since`, change is tracked per stored bid set rather than per bid — each procurement
        round of a period is its own set: a changed set is re-delivered with its unchanged bids
        included, so the period entries of a poll are not necessarily contiguous. A period entry may
        span more than one set, and a set that changes again mid-drain is deferred to the next poll,
        so a filtered response is not guaranteed to carry a period's complete bid set — re-fetch
        without `updated-since` to reconcile withdrawals.
      operationId: getBalancingCapacityBids
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingCapacityBidsResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/capacity/prices:
    get:
      summary: Get balancing capacity prices
      description: Returns balancing capacity prices for the specified area and reserve type within the given time period. Prices are in the specified currency per MW per hour. Supports cursor-based pagination for large result sets.
      operationId: getBalancingCapacityPrices
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingCapacityPricesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/cross-border/available-capacity:
    get:
      summary: Get cross-border available capacity
      description: |
        Returns the available capacity for balancing energy exchange across the border
        between two areas, for the specified reserve type and time period. Both border ends must be given
        (`area` and `other-area`); results cover both directions (area → other-area and other-area → area).
        The value is the per-direction capacity available for balancing energy exchange.
        Capacities are expressed in MW.

        Results are cursor-paginated: pass `limit` (1–1000, defaults to 100) and follow `nextCursor` from each
        response until `hasMore` is false.
      operationId: getCrossBorderAvailableCapacity
      parameters:
        - name: area
          in: query
          description: One end of the border (matched as either the from or the to area)
          required: true
          schema:
            $ref: '#/components/schemas/Area'
          example: 'ES'
        - name: other-area
          in: query
          description: The other end of the border (matched as either the from or the to area)
          required: true
          schema:
            $ref: '#/components/schemas/Area'
          example: 'PT'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CrossBorderAvailableCapacityResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /balancing/capacity/cross-zonal-allocation:
    get:
      summary: Get allocated cross-zonal capacity
      description: |
        Returns allocated cross-zonal capacity volumes across the border between two areas,
        for the specified reserve type and time period. Both border ends must be given (`area` and `other-area`);
        results cover both directions (area → other-area and other-area → area). Volumes are expressed in MW.
        Supports cursor-based pagination for large result sets.
      operationId: getCrossZonalCapacityAllocation
      parameters:
        - name: area
          in: query
          description: One end of the border (matched as either the from or the to area)
          required: true
          schema:
            $ref: '#/components/schemas/Area'
          example: 'FI'
        - name: other-area
          in: query
          description: The other end of the border (matched as either the from or the to area)
          required: true
          schema:
            $ref: '#/components/schemas/Area'
          example: 'EE'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CrossZonalCapacityAllocationResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/capacity/procured-volumes:
    get:
      summary: Get procured balancing capacity volumes
      description: Returns procured balancing capacity volumes for the specified area and reserve type within the given time period. Volumes are expressed in MW. Supports cursor-based pagination for large result sets.
      operationId: getBalancingCapacityProcuredVolumes
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingCapacityVolumesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/capacity/demand:
    get:
      summary: Get balancing capacity demand
      description: |
        **EXPERIMENTAL**: Returns balancing capacity demand for the specified area and reserve type within
        the given time period, i.e. the balancing capacity the TSO set out to procure. Demand is expressed
        in MW and grouped per procurement (`procurement.procuredAt`), so it can be compared against the
        procured volumes of the same procurement.

        Each group carries a `demandBasis`: `additive` demand adds to the delivery period's total
        requirement, while `substitutive` demand restates demand already represented by another procurement
        of the same period (e.g. a re-run after a failed auction). When summing a period's total requirement
        across procurements, sum additive demand only.

        Total demand is the full requirement; local demand is the part that must be procured within the
        area itself, so total minus local may be covered from other areas.
        Supports cursor-based pagination for large result sets.

        This endpoint is experimental and may be changed or removed without a deprecation period.
      operationId: getBalancingCapacityDemand
      x-experimental: true
      parameters:
        - $ref: '#/components/parameters/area'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalancingCapacityDemandsResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/cross-border-marginal-prices:
    get:
      summary: Get cross-border marginal prices
      description: |
        **Experimental** - This endpoint is under active development and may change without notice.

        Returns cross-border purchased marginal prices (CBPMs) for the specified area and reserve type within the given time period.
        Supports cursor-based pagination for large result sets.
      operationId: getCrossBorderMarginalPrices
      parameters:
        - name: area
          in: query
          description: The area for which to retrieve data
          required: true
          schema:
            $ref: '#/components/schemas/Area'
          example: 'AT'
        - name: period-start-at
          in: query
          description: Start of the time period (UTC)
          required: true
          schema:
            type: string
            format: date-time
            example: '2026-03-01T00:00:00Z'
        - name: period-end-at
          in: query
          description: End of the time period (UTC)
          required: true
          schema:
            type: string
            format: date-time
            example: '2026-03-01T01:00:00Z'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 1000, max 10000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 10000
            default: 1000
            example: 1000
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CrossBorderMarginalPricesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /balancing/energy/cross-border-volumes:
    get:
      summary: Get cross-border balancing energy volumes
      description: |
        Returns cross-border balancing energy volumes across the border between two areas,
        for the specified reserve type and time period. Both border ends must be given (`area` and `other-area`);
        results cover both directions (area → other-area and other-area → area). Volumes are expressed as average power in MW
        and split by activation type — for mFRR, direct and scheduled activations are returned as separate entries,
        and volumes without a direct/scheduled breakdown come back as a single unspecified entry.
        Supports cursor-based pagination for large result sets.
      operationId: getCrossBorderEnergyVolumes
      parameters:
        - name: area
          in: query
          description: One end of the border (matched as either the from or the to area)
          required: true
          schema:
            $ref: '#/components/schemas/Area'
          example: 'FI'
        - name: other-area
          in: query
          description: The other end of the border (matched as either the from or the to area)
          required: true
          schema:
            $ref: '#/components/schemas/Area'
          example: 'EE'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/reserve-type'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CrossBorderEnergyVolumesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

  /energy/day-ahead/prices:
    get:
      summary: Get day-ahead energy prices
      description: |
        **EXPERIMENTAL**: Returns day-ahead wholesale electricity prices for the specified bidding zone
        within the given time period. Prices are returned in the bidding zone's native currency per MWh,
        as published by the relevant power exchange. Supports cursor-based pagination for large result
        sets.

        Coverage is limited to bidding zones whose day-ahead prices are published under CC BY 4.0
        or an equivalently permissive license that allows redistribution.

        This endpoint is experimental and may be changed or removed without a deprecation period.
      operationId: getDayAheadEnergyPrices
      x-experimental: true
      parameters:
        - name: area
          in: query
          description: The bidding zone for which to retrieve day-ahead prices
          required: true
          schema:
            $ref: '#/components/schemas/Area'
          example: 'FI'
        - $ref: '#/components/parameters/period-start-at'
        - $ref: '#/components/parameters/period-end-at'
        - $ref: '#/components/parameters/cursor'
        - name: limit
          in: query
          description: Maximum number of results to return (default 100, max 1000)
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
            example: 100
        - $ref: '#/components/parameters/updated-since'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DayAheadEnergyPricesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'

components:
  parameters:
    area:
      name: area
      in: query
      description: The area for which to retrieve data
      required: true
      schema:
        $ref: '#/components/schemas/Area'
      example: 'EE'
    period-start-at:
      name: period-start-at
      in: query
      description: Start of the time period (UTC)
      required: true
      schema:
        type: string
        format: date-time
        example: '2025-01-01T00:00:00Z'
    period-end-at:
      name: period-end-at
      in: query
      description: End of the time period (UTC)
      required: true
      schema:
        type: string
        format: date-time
        example: '2025-01-02T00:00:00Z'
    reserve-type:
      name: reserve-type
      in: query
      description: Filter by reserve type
      required: true
      schema:
        $ref: '#/components/schemas/ReserveType'
      example: 'aFRR'
    cursor:
      name: cursor
      in: query
      description: Pagination cursor from previous response. Omit to start from the beginning.
      required: false
      schema:
        type: string
        example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
    updated-since:
      name: updated-since
      in: query
      description: >-
        Only return records the backend stored a change for strictly after this timestamp (UTC).
        Combine with the mandatory period window to poll incrementally for changes instead of
        re-downloading the full window. Pass back the `nextUpdatedSince` of your previous poll over
        the same window — a timestamp you derive yourself can silently skip changes.
        Like all query parameters, repeat the same value on every page of a paginated drain.
      required: false
      schema:
        type: string
        format: date-time
        example: '2025-01-02T09:15:00Z'

  responses:
    BadRequest:
      description: Bad request
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            invalid-parameter:
              $ref: '#/components/examples/problem-invalid-parameter'
    Unauthorized:
      description: Unauthorized
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            unauthorized:
              $ref: '#/components/examples/problem-unauthorized'
    Forbidden:
      description: Forbidden
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            forbidden:
              $ref: '#/components/examples/problem-forbidden'
    NotFound:
      description: Not found
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            not-found:
              $ref: '#/components/examples/problem-not-found'
    TooManyRequests:
      description: Too many requests
      headers:
        Retry-After:
          description: Number of seconds to wait before retrying
          schema:
            type: integer
            example: 12
        X-RateLimit-Limit:
          description: Maximum number of requests allowed per minute
          schema:
            type: integer
            example: 60
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            rate-limited:
              $ref: '#/components/examples/problem-rate-limited'
    InternalServerError:
      description: Internal server error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            internal-error:
              $ref: '#/components/examples/problem-internal-error'
    NotImplemented:
      description: Not implemented
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            not-implemented:
              $ref: '#/components/examples/problem-not-implemented'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: Enter your API token

  examples:
    problem-missing-parameter:
      summary: Missing required parameter
      value:
        type: missing-parameter
        title: Missing Parameter
        status: 400
        detail: Required parameter 'area' is missing
    problem-invalid-parameter:
      summary: Invalid parameter value
      value:
        type: invalid-parameter
        title: Invalid Parameter
        status: 400
        detail: The area parameter value is not valid
    problem-unauthorized:
      summary: Missing or invalid authentication
      value:
        type: unauthorized
        title: Unauthorized
        status: 401
        detail: Valid API token required
    problem-forbidden:
      summary: Insufficient permissions
      value:
        type: forbidden
        title: Forbidden
        status: 403
        detail: Access to this resource is not allowed
    problem-not-found:
      summary: Resource not found
      value:
        type: not-found
        title: Not Found
        status: 404
        detail: The requested resource was not found
    problem-not-implemented:
      summary: Feature not yet implemented
      value:
        type: not-implemented
        title: Not Implemented
        status: 501
        detail: This feature is not yet available
    problem-rate-limited:
      summary: Too many requests
      value:
        type: rate-limited
        title: Rate Limited
        status: 429
        detail: Request limit exceeded. Please try again later
    problem-internal-error:
      summary: Server error
      value:
        type: internal-error
        title: Internal Server Error
        status: 500
        detail: An unexpected error occurred while processing the request

  schemas:
    NextUpdatedSince:
      type: string
      format: date-time
      description: >-
        The watermark to pass as `updated-since` on the next poll. Every page of one drain reports
        the same value. It deliberately lags real time to cover writes that were still committing,
        so consecutive polls overlap slightly and a record may be delivered more than once — upsert
        on consume.
      example: '2025-01-02T09:15:00Z'
    ImbalancePricesResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/ImbalancePrices'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: true
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    ImbalancePrices:
      type: object
      required:
        - area
        - eicCode
        - currency
        - direction
        - prices
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        currency:
          $ref: '#/components/schemas/Currency'
        direction:
          $ref: '#/components/schemas/ImbalanceDirection'
        prices:
          type: array
          items:
            $ref: '#/components/schemas/ImbalancePrice'

    ImbalancePrice:
      type: object
      required:
        - period
        - pricePerMwh
      properties:
        period:
          $ref: '#/components/schemas/Period'
        pricePerMwh:
          type: number
          description: Price per MWh in the specified currency
          example: 45.50

    ImbalancePriceForecastsResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/ImbalancePriceForecasts'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    ImbalancePriceForecasts:
      type: object
      required:
        - area
        - eicCode
        - currency
        - direction
        - forecasts
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        currency:
          $ref: '#/components/schemas/Currency'
        direction:
          $ref: '#/components/schemas/ImbalanceDirection'
        forecasts:
          type: array
          items:
            $ref: '#/components/schemas/ImbalancePriceForecast'

    ImbalancePriceForecast:
      type: object
      required:
        - period
        - quantiles
        - madeAt
        - degraded
      properties:
        period:
          $ref: '#/components/schemas/Period'
        quantiles:
          type: array
          description: >-
            The predictive distribution of the price, as one level/price pair per quantile level,
            ascending by level. Each forecast states the grid it was made on — read the levels off
            it rather than indexing by a position you hardcoded.
          items:
            $ref: '#/components/schemas/ImbalancePriceForecastQuantile'
        madeAt:
          type: string
          format: date-time
          description: When this forecast was made (UTC).
          example: '2025-01-01T00:05:00Z'
        degraded:
          type: boolean
          description: >-
            True when the forecast was computed from incomplete or stale inputs. It is still
            served, but is less trustworthy — use with care.
          example: false

    ImbalancePriceForecastQuantile:
      type: object
      required:
        - level
        - pricePerMwh
      properties:
        level:
          type: number
          description: >-
            The quantile level, as a decimal strictly between 0 and 1 — 0.5 being the median, and
            the pair 0.1/0.9 bounding the central 80% interval.
          minimum: 0
          exclusiveMinimum: true
          maximum: 1
          exclusiveMaximum: true
          example: 0.5
        pricePerMwh:
          type: number
          description: Forecast price per MWh at this level, in the group's currency
          example: 45.50

    ImbalancePriceHistoryResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/ImbalancePriceHistory'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    ImbalancePriceHistory:
      type: object
      required:
        - area
        - eicCode
        - currency
        - direction
        - prices
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        currency:
          $ref: '#/components/schemas/Currency'
        direction:
          $ref: '#/components/schemas/ImbalanceDirection'
        prices:
          type: array
          items:
            $ref: '#/components/schemas/ImbalancePriceRevision'

    ImbalancePriceRevision:
      type: object
      required:
        - period
        - pricePerMwh
        - observedAt
      properties:
        period:
          $ref: '#/components/schemas/Period'
        pricePerMwh:
          type: number
          description: Price per MWh in the specified currency
          example: 45.50
        observedAt:
          type: string
          format: date-time
          description: When this revision was recorded (UTC)
          example: '2026-08-04T10:07:31Z'

    ImbalanceTotalVolumesResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/ImbalanceTotalVolumes'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    ImbalanceTotalVolumes:
      type: object
      required:
        - area
        - eicCode
        - volumes
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        volumes:
          type: array
          items:
            $ref: '#/components/schemas/TotalImbalanceVolume'
          description: Array of total imbalance volumes for each period, direction can vary per period

    TotalImbalanceVolume:
      type: object
      required:
        - period
        - averagePowerInMw
        - direction
      properties:
        period:
          $ref: '#/components/schemas/Period'
        averagePowerInMw:
          type: number
          description: Average power in MW during the period
          example: 60.5
        direction:
          $ref: '#/components/schemas/TotalImbalanceDirection'

    ImbalanceTotalVolumeHistoryResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/ImbalanceTotalVolumeHistory'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    ImbalanceTotalVolumeHistory:
      type: object
      required:
        - area
        - eicCode
        - volumes
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        volumes:
          type: array
          items:
            $ref: '#/components/schemas/TotalImbalanceVolumeRevision'
          description: Revision entries, each period's ascending by observedAt; direction can vary per entry

    TotalImbalanceVolumeRevision:
      type: object
      required:
        - period
        - averagePowerInMw
        - direction
        - observedAt
      properties:
        period:
          $ref: '#/components/schemas/Period'
        averagePowerInMw:
          type: number
          description: Average power in MW during the period
          example: 60.5
        direction:
          $ref: '#/components/schemas/TotalImbalanceDirection'
        observedAt:
          type: string
          format: date-time
          description: When this revision was recorded (UTC)
          example: '2026-08-04T10:07:31Z'

    BalancingEnergyVolumesResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyVolumes'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: true
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    BalancingEnergyVolumes:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - activationType
        - standardProduct
        - volumes
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        activationType:
          $ref: '#/components/schemas/ActivationType'
        standardProduct:
          type: boolean
          description: Indicates if this is a European standard balancing product
          example: true
        volumes:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyVolume'

    BalancingEnergyVolume:
      type: object
      required:
        - period
        - volumeInMw
      properties:
        period:
          $ref: '#/components/schemas/Period'
        volumeInMw:
          type: number
          description: Average power in MW over the period
          example: 250.5

    BalancingEnergyActivatedVolumeHistoryResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyActivatedVolumeHistory'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    BalancingEnergyActivatedVolumeHistory:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - activationType
        - standardProduct
        - volumes
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        activationType:
          $ref: '#/components/schemas/ActivationType'
        standardProduct:
          type: boolean
          description: Indicates if this is a European standard balancing product
          example: true
        volumes:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyActivatedVolumeRevision'

    BalancingEnergyActivatedVolumeRevision:
      type: object
      required:
        - period
        - volumeInMw
        - observedAt
      properties:
        period:
          $ref: '#/components/schemas/Period'
        volumeInMw:
          type: number
          description: Average power in MW over the period
          example: 250.5
        observedAt:
          type: string
          format: date-time
          description: When this revision was recorded (UTC)
          example: '2026-08-19T10:07:31Z'

    BalancingEnergyOfferedVolumeHistoryResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyOfferedVolumeHistory'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    BalancingEnergyOfferedVolumeHistory:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - activationType
        - standardProduct
        - volumes
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        activationType:
          $ref: '#/components/schemas/ActivationType'
        standardProduct:
          type: boolean
          description: Indicates if this is a European standard balancing product
          example: true
        volumes:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyOfferedVolumeRevision'

    BalancingEnergyOfferedVolumeRevision:
      type: object
      required:
        - period
        - volumeInMw
        - observedAt
      properties:
        period:
          $ref: '#/components/schemas/Period'
        volumeInMw:
          type: number
          description: Average power in MW over the period
          example: 250.5
        observedAt:
          type: string
          format: date-time
          description: When this revision was recorded (UTC)
          example: '2026-08-19T10:07:31Z'

    BalancingEnergyPricesResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyPrices'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    BalancingEnergyPrices:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - activationType
        - currency
        - standardProduct
        - prices
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        activationType:
          $ref: '#/components/schemas/ActivationType'
        currency:
          $ref: '#/components/schemas/Currency'
        standardProduct:
          type: boolean
          description: Indicates if this is a European standard balancing product
          example: true
        prices:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyPrice'

    BalancingEnergyPrice:
      type: object
      required:
        - period
        - pricePerMwh
      properties:
        period:
          $ref: '#/components/schemas/Period'
        pricePerMwh:
          type: number
          description: Price per MWh in the specified currency
          example: 45.50

    BalancingEnergyPriceHistoryResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyPriceHistory'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    BalancingEnergyPriceHistory:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - activationType
        - currency
        - standardProduct
        - prices
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        activationType:
          $ref: '#/components/schemas/ActivationType'
        currency:
          $ref: '#/components/schemas/Currency'
        standardProduct:
          type: boolean
          description: Indicates if this is a European standard balancing product
          example: true
        prices:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyPriceRevision'

    BalancingEnergyPriceRevision:
      type: object
      required:
        - period
        - pricePerMwh
        - observedAt
      properties:
        period:
          $ref: '#/components/schemas/Period'
        pricePerMwh:
          type: number
          description: Price per MWh in the specified currency
          example: 45.50
        observedAt:
          type: string
          format: date-time
          description: When this revision was recorded (UTC)
          example: '2026-08-19T10:07:31Z'

    DayAheadEnergyPricesResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/DayAheadEnergyPrices'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    DayAheadEnergyPrices:
      type: object
      required:
        - area
        - eicCode
        - currency
        - prices
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        currency:
          $ref: '#/components/schemas/Currency'
        prices:
          type: array
          items:
            $ref: '#/components/schemas/DayAheadEnergyPrice'

    DayAheadEnergyPrice:
      type: object
      required:
        - period
        - pricePerMwh
      properties:
        period:
          $ref: '#/components/schemas/Period'
        pricePerMwh:
          type: number
          description: Day-ahead price per MWh in the specified currency
          example: 45.67

    BalancingEnergyBidsResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyBids'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: true
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    BalancingEnergyBids:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - currency
        - standardProduct
        - periods
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        currency:
          $ref: '#/components/schemas/Currency'
        standardProduct:
          type: boolean
          description: Indicates if this is a European standard balancing product
          example: true
        periods:
          type: array
          description: >-
            One entry per delivery period for this group, ascending by period start. When a page ends
            inside a delivery period (`hasMore` is true), the next page continues the same entry — merge
            entries on the group's dimensions plus the period when accumulating pages.
          items:
            $ref: '#/components/schemas/BalancingEnergyBidPeriod'

    BalancingEnergyBidPeriod:
      type: object
      required:
        - period
        - bids
      properties:
        period:
          $ref: '#/components/schemas/Period'
        bids:
          type: array
          description: >-
            The bids for this delivery period. No ordering is guaranteed — sort by price client-side if
            you need the merit order.
          items:
            $ref: '#/components/schemas/EnergyBid'

    EnergyBid:
      type: object
      required:
        - volumeInMw
        - pricePerMwh
      properties:
        volumeInMw:
          type: number
          description: Bid volume in MW
          example: 100
        pricePerMwh:
          type: number
          description: Bid price per MWh in the specified currency
          example: 55.25

    BalancingCapacityBidsResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/BalancingCapacityBids'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: true
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    BalancingCapacityBids:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - currency
        - periods
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        currency:
          $ref: '#/components/schemas/Currency'
        periods:
          type: array
          description: >-
            One entry per delivery period for this group, ascending by period start. When a page ends
            inside a delivery period (`hasMore` is true), the next page continues the same entry — merge
            entries on the group's dimensions plus the period when accumulating pages.
          items:
            $ref: '#/components/schemas/BalancingCapacityBidPeriod'

    BalancingCapacityBidPeriod:
      type: object
      required:
        - period
        - bids
      properties:
        period:
          $ref: '#/components/schemas/Period'
        bids:
          type: array
          description: >-
            The bids for this delivery period. No ordering is guaranteed — sort by price client-side if
            you need the merit order.
          items:
            $ref: '#/components/schemas/CapacityBid'

    CapacityBid:
      type: object
      required:
        - capacityInMw
        - pricePerMwPerHour
        - status
        - procurement
      properties:
        capacityInMw:
          type: number
          description: Bid capacity in MW
          example: 50
        pricePerMwPerHour:
          type: number
          description: Bid price per MW per hour in the specified currency
          example: 12.50
        status:
          $ref: '#/components/schemas/BidStatus'
        procurement:
          description: The procurement this bid was submitted to.
          allOf:
            - $ref: '#/components/schemas/Procurement'

    Procurement:
      type: object
      required:
        - procuredAt
      properties:
        procuredAt:
          type: string
          format: date-time
          description: |
            Timestamp when the capacity was procured (allocation time or gate closure time).
            Used to distinguish different procurements (e.g. yearly vs hourly, or multiple procurement rounds).
          example: "2024-08-15T14:30:00Z"

    BalancingCapacityPricesResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/BalancingCapacityPrices'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    BalancingCapacityPrices:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - currency
        - procurement
        - prices
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        currency:
          $ref: '#/components/schemas/Currency'
        procurement:
          description: The procurement these prices came from.
          allOf:
            - $ref: '#/components/schemas/Procurement'
        prices:
          type: array
          items:
            $ref: '#/components/schemas/BalancingCapacityPrice'

    BalancingCapacityPrice:
      type: object
      required:
        - period
        - pricePerMwPerHour
      properties:
        period:
          $ref: '#/components/schemas/Period'
        pricePerMwPerHour:
          type: number
          description: Price per MW per hour in the specified currency
          example: 12.50

    BalancingCapacityVolumesResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/BalancingCapacityVolumes'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    BalancingCapacityVolumes:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - procurement
        - volumes
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        procurement:
          description: The procurement these volumes came from.
          allOf:
            - $ref: '#/components/schemas/Procurement'
        volumes:
          type: array
          items:
            $ref: '#/components/schemas/BalancingCapacityVolume'

    BalancingCapacityVolume:
      type: object
      required:
        - period
        - volumeInMw
      properties:
        period:
          $ref: '#/components/schemas/Period'
        volumeInMw:
          type: number
          description: Volume in MW
          example: 50.0

    BalancingCapacityDemandsResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/BalancingCapacityDemands'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    BalancingCapacityDemands:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - procurement
        - demandBasis
        - demands
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        procurement:
          $ref: '#/components/schemas/Procurement'
        demandBasis:
          $ref: '#/components/schemas/DemandBasis'
        demands:
          type: array
          items:
            $ref: '#/components/schemas/BalancingCapacityDemand'

    BalancingCapacityDemand:
      type: object
      required:
        - period
        - totalDemandInMw
        - localDemandInMw
      properties:
        period:
          $ref: '#/components/schemas/Period'
        totalDemandInMw:
          type: number
          description: The full capacity requirement in MW
          example: 300.0
        localDemandInMw:
          type: number
          description: The part of the requirement in MW that must be procured within the area itself; total minus local may be covered from other areas
          example: 120.0

    Period:
      type: object
      required:
        - startAt
        - endAt
      properties:
        startAt:
          type: string
          format: date-time
          description: Start of the period (UTC)
          example: '2025-01-01T00:00:00Z'
        endAt:
          type: string
          format: date-time
          description: End of the period (UTC)
          example: '2025-01-01T01:00:00Z'

    Area:
      type: string
      description: Area code
      enum:
        - AT
        - BALTICS
        - BE
        - BG
        - CH
        - CZ
        - DE
        - DE_50HERTZ
        - DE_AMPRION
        - DE_TENNET
        - DE_TRANSNETBW
        - DK1
        - DK2
        - EE
        - ES
        - FI
        - FR
        - GR
        - HR
        - HU
        - IT
        - IT_NORTH
        - IT_CENTER_NORTH
        - IT_CENTER_SOUTH
        - IT_SOUTH
        - IT_CALABRIA
        - IT_SICILY
        - IT_SARDINIA
        - LT
        - LV
        - NL
        - NO1
        - NO2
        - NO3
        - NO4
        - NO5
        - PL
        - PT
        - RO
        - RS
        - SE1
        - SE2
        - SE3
        - SE4
        - SI
        - SK
        - UA

    EicCode:
      type: string
      description: Energy Identification Code (EIC)
      # Append new codes at the END: the generated Python client names these enum
      # members positionally (VALUE_0, VALUE_1, ...), so inserting a code mid-list
      # rebinds VALUE_N for every later code. Resolved in REST API 2.0 by switching
      # the client to Literal enums (see clients/python/config.yaml).
      enum:
        - 10YAT-APG------L
        - 10YBE----------2
        - 10YCA-BULGARIA-R
        - 10YCH-SWISSGRIDZ
        - 10YCZ-CEPS-----N
        - 10Y1001A1001A83F
        - 10YDE-VE-------2
        - 10YDE-RWENET---I
        - 10YDE-EON------1
        - 10YDE-ENBW-----N
        - 10YDK-1--------W
        - 10YDK-2--------M
        - 10Y1001A1001A39I
        - 10YES-REE------0
        - 10YFI-1--------U
        - 10YFR-RTE------C
        - 10YGR-HTSO-----Y
        - 10YHR-HEP------M
        - 10YHU-MAVIR----U
        - 10YIT-GRTN-----B
        - 10Y1001A1001A73I
        - 10Y1001A1001A70O
        - 10Y1001A1001A71M
        - 10Y1001A1001A788
        - 10Y1001C--00096J
        - 10Y1001A1001A75E
        - 10Y1001A1001A74G
        - 10YLT-1001A0008Q
        - 10YLV-1001A00074
        - 10YNL----------L
        - 10YNO-1--------2
        - 10YNO-2--------T
        - 10YNO-3--------J
        - 10YNO-4--------9
        - 10Y1001A1001A48H
        - 10YPL-AREA-----S
        - 10YPT-REN------W
        - 10YRO-TEL------P
        - 10YCS-SERBIATSOV
        - 10Y1001A1001A44P
        - 10Y1001A1001A45N
        - 10Y1001A1001A46L
        - 10Y1001A1001A47J
        - 10YSI-ELES-----O
        - 10YSK-SEPS-----K
        - 10Y1001A1001A94A
        - 10Y1001C--000182

    ReserveType:
      type: string
      description: Reserve type
      enum:
        - FCR
        - aFRR
        - mFRR
        - RR

    Direction:
      type: string
      description: Balancing direction
      enum:
        - up
        - symmetric
        - down

    DemandBasis:
      type: string
      description: |
        Whether the demand adds to the delivery period's total requirement (`additive`) or restates demand
        already represented by another procurement of the same period (`substitutive`), e.g. a re-run after
        a failed auction. When summing a period's total requirement across procurements, sum additive demand only.
      enum:
        - additive
        - substitutive

    ImbalanceDirection:
      type: string
      description: Imbalance direction
      enum:
        - positive
        - symmetric
        - negative

    TotalImbalanceDirection:
      type: string
      description: |
        Total imbalance volume direction (ENTSO-E regulatory terminology):
        - surplus: Generation exceeds consumption (D > 0, positive imbalance)
        - deficit: Consumption exceeds generation (D < 0, negative imbalance)
        - balanced: Generation equals consumption (D = 0)
      enum:
        - surplus
        - deficit
        - balanced

    Currency:
      type: string
      description: Currency code
      enum:
        - BGN
        - CHF
        - EUR
        - HUF
        - PLN
        - RON
        - UAH

    ActivationType:
      type: string
      description: |
        Activation type of the balancing energy. Only mFRR distinguishes activation types:
        - direct: mFRR activated directly
        - scheduled: mFRR activated on a schedule
        - unspecified: mFRR without a direct/scheduled breakdown — the source does not publish one, or the product does not define one
        - notApplicable: the reserve type has no activation-type concept (FCR, aFRR, RR)
      enum:
        - direct
        - scheduled
        - unspecified
        - notApplicable

    BidStatus:
      type: string
      description: |
        Status of a capacity bid:
        - offered: Bid was offered but not accepted
        - accepted: Bid was accepted (at least partially accepted)
      enum:
        - offered
        - accepted

    Problem:
      type: object
      required:
        - type
        - status
        - title
      properties:
        type:
          type: string
          description: |
            Machine-readable slug identifying the problem type. Treat this as an open
            set: new types may be introduced without a major-version bump, so match the
            values you handle and fall back on `status` for anything you don't recognise.
            Currently defined:
            `missing-parameter`, `invalid-parameter`, `unauthorized`, `forbidden`,
            `not-found`, `rate-limited`, `not-implemented`, `internal-error`.
          example: not-found
        title:
          type: string
          description: Short, human-readable summary of the problem type
        status:
          type: integer
          description: HTTP status code
        detail:
          type: string
          description: Human-readable explanation specific to this occurrence

    CrossBorderAvailableCapacityResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/CrossBorderAvailableCapacity'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    CrossBorderAvailableCapacity:
      type: object
      required:
        - fromArea
        - fromEicCode
        - toArea
        - toEicCode
        - reserveType
        - availableCapacities
      properties:
        fromArea:
          $ref: '#/components/schemas/Area'
        fromEicCode:
          $ref: '#/components/schemas/EicCode'
        toArea:
          $ref: '#/components/schemas/Area'
        toEicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        availableCapacities:
          type: array
          items:
            $ref: '#/components/schemas/CrossBorderAvailableCapacityValue'

    CrossBorderAvailableCapacityValue:
      type: object
      required:
        - period
        - availableCapacityInMw
      properties:
        period:
          $ref: '#/components/schemas/Period'
        availableCapacityInMw:
          type: number
          description: Available capacity for balancing exchange in MW
          example: 150.0

    CrossZonalCapacityAllocationResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/CrossZonalVolumes'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    CrossZonalVolumes:
      type: object
      required:
        - fromArea
        - fromEicCode
        - toArea
        - toEicCode
        - reserveType
        - volumes
      properties:
        fromArea:
          $ref: '#/components/schemas/Area'
        fromEicCode:
          $ref: '#/components/schemas/EicCode'
        toArea:
          $ref: '#/components/schemas/Area'
        toEicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        volumes:
          type: array
          items:
            $ref: '#/components/schemas/BalancingCapacityVolume'

    CrossBorderMarginalPricesResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/CrossBorderMarginalPrices'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: true
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    CrossBorderMarginalPrices:
      type: object
      required:
        - area
        - eicCode
        - reserveType
        - direction
        - currency
        - prices
      properties:
        area:
          $ref: '#/components/schemas/Area'
        eicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        direction:
          $ref: '#/components/schemas/Direction'
        currency:
          $ref: '#/components/schemas/Currency'
        prices:
          type: array
          items:
            $ref: '#/components/schemas/CrossBorderMarginalPrice'

    CrossBorderMarginalPrice:
      type: object
      required:
        - period
        - pricePerMwh
      properties:
        period:
          $ref: '#/components/schemas/Period'
        pricePerMwh:
          type: number
          description: Marginal price per MWh in the specified currency
          example: 45.50

    CrossBorderEnergyVolumesResponse:
      type: object
      required:
        - queriedPeriod
        - data
        - hasMore
        - nextUpdatedSince
      properties:
        queriedPeriod:
          $ref: '#/components/schemas/Period'
        data:
          type: array
          items:
            $ref: '#/components/schemas/CrossBorderEnergyVolumes'
        nextCursor:
          type: string
          description: Cursor to fetch the next page of results. Null if no more results.
          example: 'v1:AAAAAYwBAgMEBQYHCAkKCw=='
          nullable: true
        hasMore:
          type: boolean
          description: Indicates whether there are more results available
          example: false
        nextUpdatedSince:
          $ref: '#/components/schemas/NextUpdatedSince'

    CrossBorderEnergyVolumes:
      type: object
      required:
        - fromArea
        - fromEicCode
        - toArea
        - toEicCode
        - reserveType
        - activationType
        - volumes
      properties:
        fromArea:
          $ref: '#/components/schemas/Area'
        fromEicCode:
          $ref: '#/components/schemas/EicCode'
        toArea:
          $ref: '#/components/schemas/Area'
        toEicCode:
          $ref: '#/components/schemas/EicCode'
        reserveType:
          $ref: '#/components/schemas/ReserveType'
        activationType:
          $ref: '#/components/schemas/ActivationType'
        volumes:
          type: array
          items:
            $ref: '#/components/schemas/BalancingEnergyVolume'
