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

# Get telemetry history

> Measurements taken during `[start, end)`, in ascending `measured_at` order.
Points are returned as reported by the manufacturer, without interpolation, so
their spacing can be irregular and can differ between batteries.




## OpenAPI

````yaml /openapi.yaml get /bat/v1/{id}/telemetry
openapi: 3.1.0
info:
  title: Kapa Energy Battery API
  version: 1.0.0-draft.1
  summary: One API to control and monitor residential batteries across manufacturers.
  description: >
    The Kapa Energy Battery API gives HEMS and VPP operators a single interface
    to send

    commands to residential batteries and read their telemetry, whatever the

    manufacturer. Kapa translates each request into the manufacturer's own cloud
    API.


    ## Conventions


    ### Time

    - Timestamps are RFC 3339, in UTC, with a `Z` suffix:
    `2026-11-12T18:00:00Z`.

    - Durations are ISO 8601: `PT15M`.

    - Time windows are half-open, `[start, end)`: `start` is included, `end` is
    excluded.


    ### Power

    Power is in watts (W), as integers.

    - **Positive (+)**: the battery is discharging, or the site is exporting to
    the grid.

    - **Negative (−)**: the battery is charging, or the site is importing from
    the grid.


    Nominal ratings such as `nominal_charge_power_w` are magnitudes and are
    always positive.


    ### Energy

    Energy is in watt-hours (Wh), as integers. Battery levels are expressed as
    stored

    energy in Wh rather than state of charge in %, because the meaning of SoC
    differs

    between manufacturers. Stored energy is measured against the usable
    capacity: it

    ranges from 0 to `usable_capacity_wh`.


    ### Telemetry

    - Each data point carries two times: `measured_at`, when the device took the
      measurement, and `received_at`, when Kapa retrieved it from the manufacturer's cloud.
    - Data points are never interpolated or resampled. Each point is an actual
      measurement reported by the manufacturer. Units, signs and field names are
      standardised across manufacturers; a field the manufacturer does not report is `null`.

    ## Commands

    - Commands are asynchronous. Command endpoints return `202 Accepted` with a
    command
      whose `status` then evolves. Follow it with `GET /bat/v1/{id}/commands` or the
      `command.status_changed` webhook.
    - A `start` in the past is treated as the time Kapa accepts the command.

    - **Overlaps:** when a new command overlaps existing commands on the same
    battery,
      the newest command takes precedence over the overlapping period. Older commands
      stay in effect outside it. A command whose whole window is covered by newer
      commands becomes `superseded`.
    - Outside any command window, the battery follows its **default behaviour**:
    the
      mode its owner configured in the manufacturer's app.

    ## Idempotency

    Command and batch endpoints accept an optional `Idempotency-Key` header.
    Kapa stores

    the key with the response for 24 hours. A retry with the same key and the
    same body

    returns the original response without sending anything again.


    ## Errors

    Errors use RFC 9457 Problem Details (`application/problem+json`). The `code`
    field is

    stable and meant for programs; `title` and `detail` are meant for humans.


    | `code` | HTTP | Meaning |

    |---|---|---|

    | `invalid_parameters` | 400 | A parameter is missing, malformed or
    inconsistent (e.g. `min_wh` greater than `max_wh`). |

    | `invalid_time_window` | 400 | `start` is not before `end`, or `end` is in
    the past. |

    | `overlapping_operations` | 400 | Two operations of a batch target the same
    battery over overlapping windows. |

    | `unauthorized` | 401 | The access token is missing, invalid or expired. |

    | `battery_not_found` | 404 | No battery with this id is accessible to the
    client. |

    | `idempotency_key_in_use` | 409 | A request with the same `Idempotency-Key`
    is still being processed. |

    | `action_not_supported` | 422 | The battery cannot apply this command or
    parameter (e.g. `allow_import: false`). |

    | `energy_out_of_range` | 422 | An energy level exceeds the battery's usable
    capacity. |

    | `idempotency_key_reused` | 422 | The `Idempotency-Key` was already used
    with a different request body. |


    ## Webhooks

    Kapa pushes telemetry and command status changes to an HTTPS endpoint.
    Delivery is

    at least once and not ordered: deduplicate with `event_id`, and order data
    with

    `measured_at` or `updated_at`. Webhook registration is not covered by this
    version

    of the API.
servers:
  - url: https://api.kapa.energy
    description: Production
security:
  - oauth2: []
tags:
  - name: Authentication
    description: Obtain an OAuth 2.0 access token.
  - name: Batteries
    description: Static information about a battery.
  - name: Commands
    description: Control a single battery and follow the status of its commands.
  - name: Batches
    description: Send commands to many batteries in one request.
  - name: Telemetry
    description: Read measurements, standardised across manufacturers.
paths:
  /bat/v1/{id}/telemetry:
    parameters:
      - $ref: '#/components/parameters/BatteryId'
    get:
      tags:
        - Telemetry
      summary: Get telemetry history
      description: >
        Measurements taken during `[start, end)`, in ascending `measured_at`
        order.

        Points are returned as reported by the manufacturer, without
        interpolation, so

        their spacing can be irregular and can differ between batteries.
      operationId: getTelemetry
      parameters:
        - name: start
          in: query
          required: false
          description: >-
            Only points measured at or after this time. Defaults to `end` minus
            24 hours.
          schema:
            $ref: '#/components/schemas/Timestamp'
        - name: end
          in: query
          required: false
          description: Only points measured before this time. Defaults to now.
          schema:
            $ref: '#/components/schemas/Timestamp'
        - $ref: '#/components/parameters/Cursor'
        - name: limit
          in: query
          required: false
          description: Maximum number of points per page.
          schema:
            type: integer
            minimum: 1
            maximum: 10000
            default: 1000
      responses:
        '200':
          description: A page of telemetry points.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TelemetryPage'
              example:
                battery_id: bat_1
                points:
                  - measured_at: '2026-11-12T18:00:12Z'
                    received_at: '2026-11-12T18:02:41Z'
                    stored_energy_wh: 8400
                    battery_power_w: 3200
                    grid_power_w: 1900
                  - measured_at: '2026-11-12T18:05:09Z'
                    received_at: '2026-11-12T18:07:38Z'
                    stored_energy_wh: 8133
                    battery_power_w: 3200
                    grid_power_w: 1850
                  - measured_at: '2026-11-12T18:10:14Z'
                    received_at: '2026-11-12T18:12:44Z'
                    stored_energy_wh: 7867
                    battery_power_w: 3150
                    grid_power_w: null
                next_cursor: c_eyJ0IjoiMjAyNi0xMS0xMlQxODoxMDoxNFoifQ
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  parameters:
    BatteryId:
      name: id
      in: path
      required: true
      description: Battery identifier.
      schema:
        type: string
      example: bat_1
    Cursor:
      name: cursor
      in: query
      required: false
      description: >-
        Opaque cursor from `next_cursor` of the previous page. Keep the other
        parameters unchanged.
      schema:
        type: string
  schemas:
    Timestamp:
      type: string
      format: date-time
      pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?Z$
      description: RFC 3339 timestamp in UTC, with a `Z` suffix.
      examples:
        - '2026-11-12T18:00:00Z'
    TelemetryPage:
      type: object
      required:
        - battery_id
        - points
        - next_cursor
      properties:
        battery_id:
          type: string
          description: Battery identifier.
        points:
          type: array
          description: Points in ascending `measured_at` order.
          items:
            $ref: '#/components/schemas/TelemetryPoint'
        next_cursor:
          type:
            - string
            - 'null'
          description: Cursor for the next page. Null on the last page.
    TelemetryPoint:
      type: object
      required:
        - measured_at
        - received_at
        - stored_energy_wh
        - battery_power_w
        - grid_power_w
      properties:
        measured_at:
          $ref: '#/components/schemas/Timestamp'
          description: >-
            When the device took the measurement, as reported by the
            manufacturer.
        received_at:
          $ref: '#/components/schemas/Timestamp'
          description: When Kapa retrieved the measurement from the manufacturer's cloud.
        stored_energy_wh:
          type:
            - integer
            - 'null'
          minimum: 0
          description: >
            Energy stored in the battery, in Wh, measured against the usable
            capacity

            (from 0 to `usable_capacity_wh`).
        battery_power_w:
          type:
            - integer
            - 'null'
          description: >
            Battery power, in W. Positive when discharging, negative when
            charging.

            Measured on the side given by `power_measurement_side`.
        grid_power_w:
          type:
            - integer
            - 'null'
          description: >
            Power at the site's grid connection, in W. Positive when exporting,
            negative

            when importing. Null if not reported, e.g. when the installation has
            no grid

            meter visible to the manufacturer.
    Problem:
      type: object
      description: Error details, following RFC 9457 (Problem Details for HTTP APIs).
      required:
        - type
        - title
        - status
        - code
      properties:
        type:
          type: string
          format: uri-reference
          description: URI identifying the problem type.
        title:
          type: string
          description: Short, human-readable summary of the problem type.
        status:
          type: integer
          description: HTTP status code.
        code:
          type: string
          description: >-
            Stable, machine-readable error code. See Errors in the API
            description.
        detail:
          type: string
          description: Human-readable explanation specific to this occurrence.
        invalid_params:
          type: array
          description: Parameters that caused the error, if any.
          items:
            type: object
            required:
              - name
              - reason
            properties:
              name:
                type: string
              reason:
                type: string
  responses:
    BadRequest:
      description: The request is malformed or its parameters are invalid.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://api.kapa.energy/problems/invalid-time-window
            title: Invalid time window
            status: 400
            code: invalid_time_window
            detail: end must be after start.
            invalid_params:
              - name: end
                reason: must be after start
    Unauthorized:
      description: The access token is missing, invalid or expired.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://api.kapa.energy/problems/unauthorized
            title: Unauthorized
            status: 401
            code: unauthorized
            detail: The access token has expired.
    NotFound:
      description: No battery with this id is accessible to the client.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://api.kapa.energy/problems/battery-not-found
            title: Battery not found
            status: 404
            code: battery_not_found
            detail: No battery with id bat_9 is accessible to this client.
  securitySchemes:
    oauth2:
      type: oauth2
      description: OAuth 2.0 client credentials. Obtain a token from `POST /token`.
      flows:
        clientCredentials:
          tokenUrl: https://api.kapa.energy/token
          scopes: {}

````

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