> ## 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.

# Cancel commands

> Cancels every unfinished command on this battery (`pending`, `scheduled` or
`active`) whose window overlaps `[start, end)`. With an empty body, all current
and upcoming commands are cancelled.

Active commands stop as soon as the manufacturer applies the cancellation. The
battery then returns to its default behaviour, unless another command applies.




## OpenAPI

````yaml /openapi.yaml post /bat/v1/{id}/cancel_command
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}/cancel_command:
    parameters:
      - $ref: '#/components/parameters/BatteryId'
    post:
      tags:
        - Commands
      summary: Cancel commands
      description: >
        Cancels every unfinished command on this battery (`pending`, `scheduled`
        or

        `active`) whose window overlaps `[start, end)`. With an empty body, all
        current

        and upcoming commands are cancelled.


        Active commands stop as soon as the manufacturer applies the
        cancellation. The

        battery then returns to its default behaviour, unless another command
        applies.
      operationId: cancelCommands
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CancelRequest'
            example:
              start: '2026-11-12T18:00:00Z'
              end: '2026-11-12T20:00:00Z'
      responses:
        '202':
          description: >-
            Cancellation accepted. Lists the commands that were cancelled; empty
            if none matched.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CancelResponse'
              example:
                cancelled:
                  - command_id: cmd_610
                    battery_id: bat_1
                    action: discharge
                    parameters:
                      min_wh: 1500
                      max_wh: null
                    start: '2026-11-12T18:00:00Z'
                    end: '2026-11-12T19:00:00Z'
                    status: cancelled
                    status_reason: null
                    batch_id: null
                    created_at: '2026-11-12T16:02:51Z'
                    updated_at: '2026-11-12T16:30:18Z'
        '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
  schemas:
    CancelRequest:
      type: object
      properties:
        start:
          $ref: '#/components/schemas/NullableTimestamp'
          description: >-
            Lower bound of the window (inclusive). Omitted or null means no
            lower bound.
        end:
          $ref: '#/components/schemas/NullableTimestamp'
          description: >-
            Upper bound of the window (exclusive). Omitted or null means no
            upper bound.
      additionalProperties: false
    CancelResponse:
      type: object
      required:
        - cancelled
      properties:
        cancelled:
          type: array
          description: Commands that were cancelled. Empty if none matched.
          items:
            $ref: '#/components/schemas/Command'
    NullableTimestamp:
      type:
        - string
        - 'null'
      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, or null.
    Command:
      type: object
      required:
        - command_id
        - battery_id
        - action
        - parameters
        - start
        - end
        - status
        - status_reason
        - batch_id
        - created_at
        - updated_at
      properties:
        command_id:
          type: string
          description: Command identifier.
        battery_id:
          type: string
          description: Battery identifier.
        action:
          $ref: '#/components/schemas/Action'
        parameters:
          $ref: '#/components/schemas/CommandParameters'
        start:
          $ref: '#/components/schemas/Timestamp'
          description: >
            Effective start (inclusive). If the request omitted `start`, or gave
            a time

            in the past, this is the time Kapa accepted the command.
        end:
          $ref: '#/components/schemas/NullableTimestamp'
          description: >-
            End (exclusive). Null means open-ended, until cancelled or
            superseded.
        status:
          $ref: '#/components/schemas/CommandStatus'
        status_reason:
          type:
            - string
            - 'null'
          description: >
            Machine-readable reason when `status` is `failed`, e.g.
            `oem_rejected`,

            `oem_unreachable`, `battery_offline`. Null otherwise.
        batch_id:
          type:
            - string
            - 'null'
          description: >-
            Identifier of the batch that created the command. Null for single
            commands.
        created_at:
          $ref: '#/components/schemas/Timestamp'
          description: When Kapa accepted the command.
        updated_at:
          $ref: '#/components/schemas/Timestamp'
          description: Last status change.
    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
    Action:
      type: string
      enum:
        - charge
        - discharge
        - autoconsume
        - idle
      description: |
        - `charge`: charge the battery.
        - `discharge`: discharge the battery.
        - `autoconsume`: self-consumption.
        - `idle`: neither charge nor discharge.
    CommandParameters:
      type: object
      description: >
        Action-specific parameters, as accepted. `charge` uses `allow_import`
        and

        `max_wh`; `discharge` and `autoconsume` use `min_wh` and `max_wh`;
        `idle` has none.
      properties:
        allow_import:
          type: boolean
        min_wh:
          type:
            - integer
            - 'null'
          minimum: 0
        max_wh:
          type:
            - integer
            - 'null'
          minimum: 0
      additionalProperties: false
    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'
    CommandStatus:
      type: string
      enum:
        - pending
        - scheduled
        - active
        - completed
        - cancelled
        - superseded
        - failed
      description: >
        - `pending`: accepted by Kapa, not yet acknowledged by the
        manufacturer's cloud.

        - `scheduled`: acknowledged by the manufacturer; `start` is in the
        future.

        - `active`: in effect on the battery.

        - `completed`: the window ended normally.

        - `cancelled`: cancelled with `cancel_command`.

        - `superseded`: the whole window is covered by more recent commands.

        - `failed`: the command could not be applied; see `status_reason`.
  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.