Gridshare Partner API

The Gridshare Partner API is the operator-facing surface for utilities, DER aggregators, and energy retailers to manage residential distributed energy resources at fleet scale. v1 endpoints cover Sites, Devices, Telemetry, Operation Mode, Overlay Plans, Periodical Tariffs, Dynamic Tariffs, Flex Groups (participants and bulk membership), Flex Events and Flex Dispatch opt-outs, Prognoses with Diff Requests and Diff Orders, Counterfactuals, and on-site Visits. Authenticated via OAuth 2.0 client-credentials against Amazon Cognito; tokens expire after 1 hour. Regional production servers are developer-api.partner.us.mygridshare.com (US) and developer-api.partner.mygridshare.com (rest of world).

Gridshare Partner API is one of 3 APIs that Lunar Energy publishes on the APIs.io network, described by a machine-readable OpenAPI specification.

This API exposes 6 machine-runnable capabilities that can be deployed as REST, MCP, or Agent Skill surfaces via Naftiko.

Tagged areas include Partner, Fleet Management, Virtual Power Plant, Flex Groups, and Flex Events. The published artifact set on APIs.io includes API documentation, an OpenAPI specification, and 6 Naftiko capability specs.

Documentation

Specifications

Other Resources

OpenAPI Specification

gridshare-partner-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Gridshare Partner API
  description: |
    The Gridshare Partner API is Lunar Energy's operator-facing surface for
    utilities, retailers, and DER aggregators managing residential
    distributed energy resources at fleet scale. Covers Sites, Devices,
    Telemetry, Operation Mode, Overlay Plans, Periodical Tariffs, Dynamic
    Tariffs, Flex Groups, Flex Events, Flex Dispatches, Prognoses with
    Diff Requests and Diff Orders, Counterfactuals, and on-site Visits.

    Authentication is OAuth 2.0 client-credentials against an Amazon Cognito
    user pool. Tokens expire after 1 hour and are sent as
    `Authorization: Bearer <access_token>` on every request.
  version: v1.0
  contact:
    name: Lunar Energy
    url: https://www.gridshare.com
    email: [email protected]
  x-logo:
    url: https://www.lunarenergy.com/favicon.ico
servers:
  - url: https://developer-api.partner.us.mygridshare.com
    description: Production server (US)
  - url: https://developer-api.partner.mygridshare.com
    description: Production server (Rest of World)
  - url: https://developer-api.partner.dev0.us.mygridshare.com
    description: Development server (US)
  - url: https://developer-api.partner.dev0.mygridshare.com
    description: Development server (Rest of World)
security:
  - bearerAuth: []
tags:
  - name: Sites
    description: List, get, create, and replace sites in the partner fleet
  - name: Devices
    description: List, get, create, replace, and patch DER devices
  - name: Telemetry
    description: Retrieve time-bucketed device telemetry and counterfactuals
  - name: Operation Mode
    description: Read or change the Gridshare operation mode of a device
  - name: Plans
    description: Read or set overlay plans for short-term device dispatch
  - name: Periodical Tariffs
    description: Manage periodical (recurring) tariffs
  - name: Dynamic Tariffs
    description: Manage dynamic time-series tariffs with 7-day pagination
  - name: Flex Groups
    description: Define and manage groups of DERs participating in flex programs
  - name: Flex Events
    description: Schedule and update flex events for a flex group
  - name: Flex Dispatches
    description: Opt participants out of an active flex dispatch
  - name: Prognoses
    description: Forecasted aggregate power profiles for flex groups
  - name: Diff Requests
    description: Request and commit differential adjustments to a prognosis
  - name: Visits
    description: Record on-site visits for installation or service
paths:
  /api/v1/sites:
    get:
      operationId: listSites
      summary: List Sites
      description: List all sites the authenticated partner can access.
      tags: [Sites]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SiteList'
        '401': { $ref: '#/components/responses/Unauthorized' }
        '403': { $ref: '#/components/responses/Forbidden' }
    post:
      operationId: createSite
      summary: Create Site
      description: Create a new site in the partner fleet.
      tags: [Sites]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Site'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Site'
  /api/v1/sites/{siteId}:
    parameters:
      - $ref: '#/components/parameters/SiteId'
    get:
      operationId: getSite
      summary: Get Site
      description: Get a site by ID.
      tags: [Sites]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Site'
    put:
      operationId: replaceSite
      summary: Replace Site
      description: Override a site with new attributes.
      tags: [Sites]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Site'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Site'
  /api/v1/sites/{siteId}/topology:
    parameters:
      - $ref: '#/components/parameters/SiteId'
    get:
      operationId: getSiteTopology
      summary: Get Site Topology
      description: |
        Return the electrical topology tree of a site. Nodes with
        `"kind": "sensor"` expose an `id` that may be passed to the
        device telemetry endpoint and a `channels` array of available
        data streams.
      tags: [Sites]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Topology'
  /api/v1/devices:
    get:
      operationId: listDevices
      summary: List Devices
      description: List all devices in the partner fleet.
      tags: [Devices]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceList'
    post:
      operationId: createDevice
      summary: Create Device
      description: Create a new device.
      tags: [Devices]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Device'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Device'
  /api/v1/devices/{synthId}:
    parameters:
      - $ref: '#/components/parameters/SynthId'
    get:
      operationId: getDevice
      summary: Get Device
      description: Get a device by ID with its static properties.
      tags: [Devices]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Device'
    put:
      operationId: replaceOrCreateDevice
      summary: Replace Or Create Device
      description: Override an existing device with new properties or create one if it does not yet exist.
      tags: [Devices]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Device'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Device'
  /api/v1/devices/{synthId}/telemetry:
    parameters:
      - $ref: '#/components/parameters/SynthId'
    get:
      operationId: getDeviceTelemetry
      summary: Get Device Telemetry
      description: |
        Get time-bucketed telemetry for a device or sensor. `synthId` can be
        a device ID or a sensor ID from the site topology. Supported device
        kinds: `inverter`, `battery_pack`, `PV`, `EV`, `meter`,
        `load_control_relay`. Include `energy_Wh_increment` and
        `energy_Wh_decrement` by passing `include=default,energy`.
      tags: [Telemetry]
      parameters:
        - in: query
          name: include
          schema: { type: string }
          description: Comma-separated set of telemetry fields. `energy` is opt-in.
        - in: query
          name: start
          schema: { type: string, format: date-time }
        - in: query
          name: end
          schema: { type: string, format: date-time }
        - in: query
          name: bucket
          schema: { type: string }
          description: Time-bucket size (e.g. `PT1H`).
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Telemetry'
  /api/v1/devices/{synthId}/operationmode:
    parameters:
      - $ref: '#/components/parameters/SynthId'
    get:
      operationId: getDeviceOperationMode
      summary: Get Device Operation Mode
      description: |
        Get the current Gridshare operation mode of a device. Valid modes:
        - `Simple` — follow the simplest plan possible for the device kind
        - `Schedule` — follow a periodical plan
        - `Smart` — AI-optimized smart plan
        - `Unknown` — operation mode cannot be determined
      tags: [Operation Mode]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationMode'
    put:
      operationId: setDeviceOperationMode
      summary: Change Device Operation Mode
      description: Set the Gridshare operation mode for a device.
      tags: [Operation Mode]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OperationMode'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationMode'
  /api/v1/devices/{synthId}/plans/overlay:
    parameters:
      - $ref: '#/components/parameters/SynthId'
    get:
      operationId: getDeviceOverlayPlan
      summary: Get Device Overlay Plan
      description: Get the current overlay plan for the device.
      tags: [Plans]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OverlayPlan'
    put:
      operationId: setDeviceOverlayPlan
      summary: Set Device Overlay Plan
      description: |
        Set an overlay plan for the device. To delete an overlay plan,
        send an empty `commands` array in the request body.
      tags: [Plans]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OverlayPlan'
      responses:
        '200':
          description: OK
  /api/v1/periodicaltariffs:
    get:
      operationId: listPeriodicalTariffs
      summary: List Periodical Tariffs
      description: List all periodical tariffs.
      tags: [Periodical Tariffs]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PeriodicalTariffList'
    post:
      operationId: createPeriodicalTariff
      summary: Create Periodical Tariff
      tags: [Periodical Tariffs]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PeriodicalTariff'
      responses:
        '201':
          description: Created
  /api/v1/periodicaltariffs/{tariffId}:
    parameters:
      - $ref: '#/components/parameters/TariffId'
    get:
      operationId: getPeriodicalTariff
      summary: Get Periodical Tariff
      tags: [Periodical Tariffs]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PeriodicalTariff'
    patch:
      operationId: updatePeriodicalTariff
      summary: Update Periodical Tariff
      description: |
        Update properties of an existing periodical tariff. Append or
        rewrite pricing periods. Tariffs may have an open-ended latest
        period; PATCH-ing in a later period closes it automatically.
      tags: [Periodical Tariffs]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PeriodicalTariff'
      responses:
        '200':
          description: OK
  /api/v1/dynamictariffs:
    get:
      operationId: listDynamicTariffs
      summary: List Dynamic Tariffs
      description: List all dynamic tariffs for the calling partner account.
      tags: [Dynamic Tariffs]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DynamicTariffList'
    post:
      operationId: createDynamicTariff
      summary: Create Dynamic Tariff
      description: Create a dynamic tariff with an optional initial set of timeseries values.
      tags: [Dynamic Tariffs]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DynamicTariff'
      responses:
        '201':
          description: Created
  /api/v1/dynamictariffs/{tariffId}:
    parameters:
      - $ref: '#/components/parameters/TariffId'
    get:
      operationId: getDynamicTariff
      summary: Get Dynamic Tariff
      description: |
        Return metadata for a dynamic tariff together with a single page of
        timeseries values covering a 7-day window. Paginate via `nextToken`.
      tags: [Dynamic Tariffs]
      parameters:
        - in: query
          name: interval
          schema: { type: string }
        - in: query
          name: nextToken
          schema: { type: string }
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DynamicTariff'
    patch:
      operationId: updateDynamicTariff
      summary: Update Dynamic Tariff
      description: Append or override periods of a dynamic tariff. Existing values are not deleted.
      tags: [Dynamic Tariffs]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DynamicTariff'
      responses:
        '200':
          description: OK
  /api/v1/flexgroups:
    get:
      operationId: listFlexGroups
      summary: List Flex Groups
      tags: [Flex Groups]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FlexGroupList'
    post:
      operationId: createFlexGroup
      summary: Create Flex Group
      tags: [Flex Groups]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlexGroup'
      responses:
        '201':
          description: Created
  /api/v1/flexgroups/{flexGroupId}:
    parameters:
      - $ref: '#/components/parameters/FlexGroupId'
    get:
      operationId: getFlexGroup
      summary: Get Flex Group
      tags: [Flex Groups]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FlexGroup'
  /api/v1/flexgroups/{flexGroupId}/participants:
    parameters:
      - $ref: '#/components/parameters/FlexGroupId'
    get:
      operationId: listFlexGroupParticipants
      summary: List Flex Group Participants
      tags: [Flex Groups]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantList'
    post:
      operationId: addFlexGroupParticipant
      summary: Add Flex Group Participant
      tags: [Flex Groups]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Participant'
      responses:
        '201':
          description: Created
  /api/v1/flexgroups/{flexGroupId}/participants/{participantId}:
    parameters:
      - $ref: '#/components/parameters/FlexGroupId'
      - $ref: '#/components/parameters/ParticipantId'
    get:
      operationId: getFlexGroupParticipant
      summary: Get Flex Group Participant
      tags: [Flex Groups]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Participant'
    delete:
      operationId: deleteFlexGroupParticipant
      summary: Delete Flex Group Participant
      tags: [Flex Groups]
      responses:
        '204':
          description: Deleted
  /api/v1/flexgroups/{flexGroupId}/participants/bulk:
    parameters:
      - $ref: '#/components/parameters/FlexGroupId'
    post:
      operationId: createBulkParticipantsAction
      summary: Create Bulk Participants Action
      description: |
        Overwrite the participants of a flex group by sending a full
        replacement list. This action is irreversible.
      tags: [Flex Groups]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ParticipantList'
      responses:
        '202':
          description: Accepted
  /api/v1/flexgroups/{flexGroupId}/participants/bulk/{bulkId}:
    parameters:
      - $ref: '#/components/parameters/FlexGroupId'
      - in: path
        name: bulkId
        required: true
        schema: { type: string }
    get:
      operationId: getBulkParticipantsAction
      summary: Get Bulk Participants Action
      description: Retrieve the status of a bulk participants update.
      tags: [Flex Groups]
      responses:
        '200':
          description: OK
  /api/v1/flexevent:
    get:
      operationId: listFlexEvents
      summary: List Flex Events
      description: List all flex events within a time range, optionally filtered by group.
      tags: [Flex Events]
      parameters:
        - in: query
          name: start
          schema: { type: string, format: date-time }
        - in: query
          name: end
          schema: { type: string, format: date-time }
        - in: query
          name: flexGroupId
          schema: { type: string }
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FlexEventList'
    post:
      operationId: createFlexEvent
      summary: Create Flex Event
      description: |
        Create a flex event for a defined flex group. Supports flat-dispatch
        events that target a flat power profile across a specified window.
      tags: [Flex Events]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlexEvent'
      responses:
        '201':
          description: Created
  /api/v1/flexevents/{flexEventId}:
    parameters:
      - in: path
        name: flexEventId
        required: true
        schema: { type: string }
    patch:
      operationId: updateFlexEvent
      summary: Update Flex Event
      description: Update or cancel an existing flex event.
      tags: [Flex Events]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlexEvent'
      responses:
        '200':
          description: OK
  /api/v1/flexdispatches/{flexDispatchId}/optout:
    parameters:
      - in: path
        name: flexDispatchId
        required: true
        schema: { type: string }
    post:
      operationId: optOutFlexDispatch
      summary: Opt Out Of Flex Dispatch
      description: |
        Opt a participant out of a flex dispatch. Participants may be
        identified by site ID or participant ID. Idempotent — repeat opt-outs
        return the original opt-out details.
      tags: [Flex Dispatches]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                siteId: { type: string }
                participantId: { type: string }
                reason: { type: string }
      responses:
        '200':
          description: OK
  /api/v1/flexgroups/{flexGroupId}/prognoses:
    parameters:
      - $ref: '#/components/parameters/FlexGroupId'
    get:
      operationId: listPrognoses
      summary: List Prognoses
      description: |
        List prognoses for a specific flex group. A new prognosis is generated
        when the group forecast changes due to prediction updates or
        explicit flex actions.
      tags: [Prognoses]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PrognosisList'
  /api/v1/prognoses/{prognosisId}/prognosisdiffrequests:
    parameters:
      - in: path
        name: prognosisId
        required: true
        schema: { type: string }
    post:
      operationId: createPrognosisDiffRequest
      summary: Create Prognosis Diff Request
      description: |
        Request a modification to a prognosis profile. Allows charging or
        discharging to the network in a coordinated manner by submitting a
        differential profile over the original prognosis. Asynchronous —
        poll the Diff Request endpoint for status.
      tags: [Diff Requests]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PrognosisDiffRequest'
      responses:
        '202':
          description: Accepted
  /api/v1/prognosisdiffrequests/{prognosisDiffRequestId}:
    parameters:
      - in: path
        name: prognosisDiffRequestId
        required: true
        schema: { type: string }
    get:
      operationId: getPrognosisDiffRequest
      summary: Get Prognosis Diff Request
      description: Poll status and feasible offer for a prognosis diff request.
      tags: [Diff Requests]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PrognosisDiffRequest'
  /api/v1/prognosisdiffrequests/{prognosisDiffRequestId}/prognosisdifforders:
    parameters:
      - in: path
        name: prognosisDiffRequestId
        required: true
        schema: { type: string }
    post:
      operationId: createPrognosisDiffOrder
      summary: Create Prognosis Diff Order
      description: |
        Confirm and commit to the offer associated with a prognosis diff
        request. Commands are dispatched to the underlying devices.
      tags: [Diff Requests]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PrognosisDiffOrder'
      responses:
        '201':
          description: Created
  /api/v1/prognosisdifforders/{prognosisDiffOrderId}:
    parameters:
      - in: path
        name: prognosisDiffOrderId
        required: true
        schema: { type: string }
    get:
      operationId: getPrognosisDiffOrder
      summary: Get Prognosis Diff Order
      description: Retrieve a committed flex offer order including price and power profile.
      tags: [Diff Requests]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PrognosisDiffOrder'
  /api/v1/counterfactuals/{counterfactualName}/devices/{deviceId}/telemetry:
    parameters:
      - in: path
        name: counterfactualName
        required: true
        schema: { type: string }
      - in: path
        name: deviceId
        required: true
        schema: { type: string }
    get:
      operationId: getCounterfactualTelemetry
      summary: Get Counterfactual Telemetry
      description: |
        Counterfactual telemetry — what the device would have done if it had
        not been smartly controlled. Availability depends on the
        counterfactuals enabled for your partner account.
      tags: [Telemetry]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Telemetry'
  /api/v1/visits:
    get:
      operationId: listVisits
      summary: List Visits
      tags: [Visits]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VisitList'
    post:
      operationId: createVisit
      summary: Create Visit
      tags: [Visits]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Visit'
      responses:
        '201':
          description: Created
  /api/v1/visits/{visitId}:
    parameters:
      - in: path
        name: visitId
        required: true
        schema: { type: string }
    get:
      operationId: getVisit
      summary: Get Visit
      tags: [Visits]
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Visit'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        OAuth 2.0 client-credentials access token obtained from the
        Gridshare partner Cognito authentication endpoint.
  parameters:
    SiteId:
      in: path
      name: siteId
      required: true
      schema: { type: string }
    SynthId:
      in: path
      name: synthId
      required: true
      schema: { type: string }
      description: A device ID or a sensor ID from the site topology.
    TariffId:
      in: path
      name: tariffId
      required: true
      schema: { type: string }
    FlexGroupId:
      in: path
      name: flexGroupId
      required: true
      schema: { type: string }
    ParticipantId:
      in: path
      name: participantId
      required: true
      schema: { type: string }
  responses:
    Unauthorized:
      description: 401 Unauthorized
      content:
        application/json:
          schema: { $ref: '#/components/schemas/UnauthorizedResponse' }
    Forbidden:
      description: 403 Forbidden
      content:
        application/json:
          schema: { $ref: '#/components/schemas/ForbiddenResponse' }
  schemas:
    Site:
      type: object
      required: [siteId]
      properties:
        siteId: { type: string }
        name: { type: string }
        timezone: { type: string }
        address:
          type: object
          properties:
            country: { type: string }
            region: { type: string }
            city: { type: string }
            postalCode: { type: string }
            line1: { type: string }
    SiteListItem:
      type: object
      required: [siteId]
      properties:
        siteId: { type: string }
    SiteList:
      type: object
      required: [entries]
      properties:
        entries:
          type: array
          items: { $ref: '#/components/schemas/SiteListItem' }
    TopologyNode:
      type: object
      properties:
        id: { type: string }
        kind:
          type: string
          enum: [site, device, sensor]
        channels:
          type: array
          items: { type: string }
        children:
          type: array
          items: { $ref: '#/components/schemas/TopologyNode' }
    Topology:
      type: object
      properties:
        root: { $ref: '#/components/schemas/TopologyNode' }
    Device:
      type: object
      required: [synthId]
      properties:
        synthId: { type: string }
        deviceId: { type: string }
        kind:
          type: string
          enum: [inverter, battery_pack, PV, EV, meter, load_control_relay]
        type: { type: string }
        siteId: { type: string }
        manufacturer: { type: string }
        model: { type: string }
        serialNumber: { type: string }
        properties:
          type: object
          additionalProperties: true
    DeviceListItem:
      type: object
      required: [synthId]
      properties:
        synthId: { type: string }
    DeviceList:
      type: object
      required: [entries]
      properties:
        entries:
          type: array
          items: { $ref: '#/components/schemas/DeviceListItem' }
    Telemetry:
      type: object
      properties:
        entries:
          type: array
          items:
            type: object
            properties:
              timestamp: { type: string, format: date-time }
              power_W: { type: number }
              voltage_V: { type: number }
              current_A: { type: number }
              stateOfCharge_pct: { type: number }
              energy_Wh_increment: { type: number }
              energy_Wh_decrement: { type: number }
    OperationMode:
      type: object
      required: [mode]
      properties:
        mode:
          type: string
          enum: [Simple, Schedule, Smart, Unknown]
    OverlayPlanCommand:
      type: object
      properties:
        start: { type: string, format: date-time }
        end: { type: string, format: date-time }
        action:
          type: string
          enum: [charge, discharge, hold, follow]
        powerLimit_W: { type: number }
    OverlayPlan:
      type: object
      required: [commands]
      properties:
        commands:
          type: array
          items: { $ref: '#/components/schemas/OverlayPlanCommand' }
    TariffExceptionPeriod:
      type: object
      properties:
        start: { type: string, format: date }
        end: { type: string, format: date }
        rate: { type: number }
    PricingPeriod:
      type: object
      properties:
        start: { type: string, format: date }
        end: { type: string, format: date }
        rates:
          type: array
          items:
            type: object
            properties:
              dayOfWeek: { type: string }
              from: { type: string }
              to: { type: string }
              price: { type: number }
        exceptions:
          type: array
          items: { $ref: '#/components/schemas/TariffExceptionPeriod' }
    PeriodicalTariff:
      type: object
      required: [name, companyName]
      properties:
        tariffId: { type: string }
        name: { type: string }
        companyName: { type: string }
        currency: { type: string }
        pricingPeriods:
          type: array
          items: { $ref: '#/components/schemas/PricingPeriod' }
    PeriodicalTariffList:
      type: object
      properties:
        entries:
          type: array
          items: { $ref: '#/components/schemas/PeriodicalTariff' }
    DynamicTariffValue:
      type: object
      properties:
        timestamp: { type: string, format: date-time }
        price: { type: number }
    DynamicTariff:
      type: object
      properties:
        tariffId: { type: string }
        name: { type: string }
        currency: { type: string }
        values:
          type: array
          items: { $ref: '#/components/schemas/DynamicTariffValue' }
        nextToken: { type: string }
    DynamicTariffList:
      type: object
      properties:
        entries:
          type: array
          items: { $ref: '#/components/schemas/DynamicTariff' }
    Participant:
      type: object
      properties:
        participantId: { type: string }
        siteId: { type: string }
        deviceIds:
          type: array
          items: { type: string }
    ParticipantList:
      type: object
      properties:
        entries:
          type: array
          items: { $ref: '#/components/schemas/Participant' }
    FlexGroup:
      type: object
      properties:
        flexGroupId: { type: string }
        name: { type: string }
        description: { type: string }
        settlementPoint: { type: string }
    FlexGroupList:
      type: object
      properties:
        entries:
          type: array
          items: { $ref: '#/components/schemas/FlexGroup' }
    FlexEvent:
      type: object
      properties:
        flexEventId: { type: string }
        flexGroupId: { type: string }
        type:
          type: string
          enum: [flatDispatch, ramp]
        start: { type: string, format: date-time }
        end: { type: string, format: date-time }
        powerProfile_W: { type: number }
        status:
          type: string
          enum: [pending, scheduled, active, completed, cancelled]
    FlexEventList:
      type: object
      properties:
 

# --- truncated at 32 KB (34 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/lunar-energy/refs/heads/main/openapi/gridshare-partner-api-openapi.yml