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

# Submit device states

> Submits state samples for up to 1,000 devices in one call. Each sample is validated alone: valid samples are stored even when others are rejected.



## OpenAPI

````yaml energy-api/reference/flatpeak-api-spec-energy.json POST /device-states
openapi: 3.0.3
info:
  description: >-
    The Flatpeak Energy API connects energy hardware (batteries, EV chargers,
    vehicles, heat pumps, water heaters, solar and generators) to electricity
    prices, grid fees, and VPP programs.


    ## Create bearer token

    Obtain a bearer token from `POST /auth/tokens` using your `account_id` and
    `secret_key` via basic auth, then send it as `Authorization: Bearer <token>`
    on every request.


    ## Base URL

    `https://energy-api.flatpeak.com`


    ## Pagination

    List endpoints return a `list` envelope with `data`, `next_cursor`, and
    `url`. Page forward by passing `next_cursor` as `cursor` on the next
    request, until it is `null`. Cursors are opaque and bound to the endpoint
    and query parameters that issued them.


    ## Errors

    Every non-2xx response uses a standard error envelope with `object`, `type`,
    `code`, and `message`. Codes are machine-readable and safe to branch on.


    ## Money

    Monetary values are decimal numbers and are always paired with a
    `currency_code` (ISO 4217). Energy is expressed in kilowatt hours (kWh).


    ## Live vs test

    `live_mode` marks live or test data.
  version: 2027-01-01.busbar
  title: Flatpeak Energy API
  termsOfService: https://flatpeak.com/legal
  contact:
    name: Technical Support
    email: support@flatpeak.com
    url: https://flatpeak.com/contact
  license:
    name: Apache 2.0
    url: https://flatpeak.com/legal
servers:
  - url: https://energy-api.flatpeak.com
security:
  - bearerAuth: []
tags:
  - name: Authentication
    description: >-
      Exchange your account credentials for a bearer token to authenticate API
      requests.
  - name: Connect
    description: >-
      Create and retrieve Connect sessions. Connect drives the user journeys for
      tariff connection, VPP enrollment, and [tariff error
      reporting](/energy-api/reference/connect/tariff/error-report). What
      happens in those journeys reaches your backend as [Connect
      webhooks](/energy-api/guides/platform/events).
    x-tariff-description: >-
      Create and retrieve Connect sessions. Connect drives the user journeys for
      tariff connection and [tariff error
      reporting](/energy-api/reference/connect/tariff/error-report). What
      happens in those journeys reaches your backend as [Connect
      webhooks](/energy-api/guides/platform/events).
  - name: Users
    description: Create, retrieve, update, delete, and list users.
  - name: Locations
    description: Create, retrieve, update, delete, and list locations.
  - name: Devices
    description: >-
      Create, retrieve, update, delete and list devices; submit and retrieve
      their state; read and write their shared settings.
  - name: Meters
    description: Submit meter records and check batch status.
  - name: Tariffs
    description: Create, retrieve, delete, and list tariffs.
  - name: Prices
    description: Retrieve and audit calculated energy prices.
  - name: Costs
    description: Calculate the monetary cost of imported or exported energy.
  - name: Optimizations
    description: >-
      Rank the connected tariff to find the best times to consume or export
      energy, as inputs to your own scheduling.
  - name: Dispatch
    description: >-
      Fetch the VPP operator's instructions for a device, and confirm what the
      device will deliver.
  - name: Events
    description: Retrieve and list account events.
  - name: VPP Enrollments
    description: Create, retrieve and list VPP enrollments, and unenroll a device.
  - name: VPP Programs
    description: List VPP programs available to devices.
  - name: VPP Events
    description: >-
      VPP events committed by VPP operators, with your fleet's share and its
      per-device allocation. You can take over the allocation while it is open.
  - name: Operator groups
    description: >-
      Read-only views of the device groups VPP operators define. You see the
      groups that touch your fleet, and only your own devices in them.
  - name: Zones
    description: >-
      Network areas VPP operators define that touch your fleet. Read-only. You
      see only your own devices in them.
externalDocs:
  description: Documentation
  url: https://docs.flatpeak.com
paths:
  /device-states:
    post:
      tags:
        - Devices
      summary: Submit device states
      description: >-
        Submits state samples for up to 1,000 devices in one call. Each sample
        is validated alone: valid samples are stored even when others are
        rejected.
      operationId: submit-device-states
      parameters: []
      requestBody:
        $ref: '#/components/requestBodies/DeviceStateBatchSubmit'
      responses:
        '200':
          $ref: '#/components/responses/DeviceStateBatch'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '403':
          $ref: '#/components/responses/403'
        '422':
          $ref: '#/components/responses/422'
        '429':
          $ref: '#/components/responses/429'
        '500':
          $ref: '#/components/responses/500'
        '503':
          $ref: '#/components/responses/503'
components:
  requestBodies:
    DeviceStateBatchSubmit:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DeviceStateBatchSubmit'
  responses:
    '400':
      description: >-
        400 Bad Request: the request was malformed or a required field is
        missing or invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    '401':
      description: '401 Unauthorized: authentication credentials are missing or invalid.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    '403':
      description: '403 Forbidden: you do not have permission to access this resource.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    '422':
      description: >-
        422 Unprocessable Entity: the request is well-formed but cannot be
        processed, for example missing required data.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    '429':
      description: '429 Too Many Requests: the rate limit has been exceeded.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    '500':
      description: >-
        500 Internal Server Error: an unexpected error occurred. Safe to retry
        with backoff.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    '503':
      description: >-
        503 Service Unavailable: the service is temporarily down for
        maintenance. Retry after the indicated delay.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    DeviceStateBatch:
      description: Device state batch response.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DeviceStateBatch'
  schemas:
    DeviceStateBatchSubmit:
      type: object
      title: DeviceStateBatchSubmit
      additionalProperties: false
      description: Device state samples for many devices in one call.
      properties:
        data:
          type: array
          minItems: 1
          maxItems: 1000
          description: >-
            One sample per entry, up to 1,000. Each entry is a device state
            submission with its `device_id`.
          items:
            allOf:
              - type: object
                properties:
                  device_id:
                    type: string
                    description: Flatpeak Device ID.
                    example: dev_63a6087272941ef077a8fd3e
                required:
                  - device_id
              - $ref: '#/components/schemas/DeviceStateSubmit'
      required:
        - data
    DeviceStateBatch:
      type: object
      title: DeviceStateBatch
      description: >-
        The result of a device state batch. Accepted samples are stored; each
        rejected one is listed with why.
      properties:
        object:
          type: string
          enum:
            - device_state_batch
          description: Object type, `device_state_batch`.
          example: device_state_batch
        live_mode:
          type: boolean
          description: '`true` for live data, `false` for test data.'
        accepted_count:
          type: integer
          description: Samples stored.
          example: 998
        rejected:
          type: array
          description: >-
            Samples not stored, with the reason. Empty when every sample was
            stored.
          items:
            type: object
            properties:
              index:
                type: integer
                description: Position of the sample in `data`, from 0.
                example: 41
              device_id:
                type: string
                description: Flatpeak Device ID.
                example: dev_9c1f70a4e2b6485db3f0c8a1
              code:
                type: string
                description: Machine-readable error code.
                example: device_not_found
              message:
                type: string
                description: Human-readable description.
                example: No device dev_9c1f70a4e2b6485db3f0c8a1 on this account.
            required:
              - index
              - device_id
              - code
              - message
        time_created:
          type: string
          format: date-time
          description: Time when the batch was received, in UTC.
          example: '2026-08-04T16:00:05Z'
      required:
        - object
        - live_mode
        - accepted_count
        - rejected
        - time_created
    Error:
      type: object
      description: Standard error envelope returned by every non-2xx response.
      required:
        - object
        - type
        - code
        - message
      properties:
        object:
          type: string
          enum:
            - error
          default: error
          description: Object type.
        type:
          type: string
          description: High-level error category.
          example: invalid_request
        code:
          type: string
          description: Machine-readable error code, safe to branch on.
          example: not_found
        message:
          type: string
          description: Human-readable description of the error.
          example: The requested resource could not be found.
        context:
          type: string
          description: Optional originating context, for example `api.price_get`.
          example: api.price_get
        live_mode:
          type: boolean
          description: Whether the error occurred against live or test data.
        time_created:
          type: string
          format: date-time
          description: Time the error was generated (RFC 3339).
          example: '2026-01-01T00:00:00Z'
    DeviceStateSubmit:
      type: object
      title: DeviceStateSubmit
      description: >-
        The current operational state of a device, grouped by subsystem. Include
        only the subsystems the device has. At least one subsystem block must be
        present.
      additionalProperties: false
      properties:
        record_reference_id:
          type: string
          example: MET1234567890
          description: >-
            Optional unique identifier for the telemetry record, used for
            idempotency and reconciliation.
        battery:
          $ref: '#/components/schemas/DeviceStateBattery'
        vehicle:
          $ref: '#/components/schemas/DeviceStateVehicle'
        evse:
          $ref: '#/components/schemas/DeviceStateEvse'
        pv:
          $ref: '#/components/schemas/DeviceStatePv'
        time_recorded:
          type: string
          example: '2026-02-01T10:30:00Z'
          description: Time the measurement was recorded, in RFC 3339 format.
          format: date-time
      required:
        - time_recorded
    DeviceStateBattery:
      title: DeviceStateBattery
      type: object
      additionalProperties: false
      description: Operational state of a stationary battery.
      properties:
        state_of_charge_percent:
          type: number
          minimum: 0
          maximum: 100
          description: >-
            Usable state of charge, as a percentage from 0 to 100. Where the
            source distinguishes usable from nominal, report usable, so capacity
            locked out by temperature or battery management is excluded.
          example: 34.2
        target_state_of_charge_percent:
          type: number
          minimum: 0
          maximum: 100
          description: >-
            State of charge the battery is working towards, as a percentage from
            0 to 100, as reported by the device. Not a shared setting.
          example: 80
        power_kw:
          type: number
          description: >-
            Current battery power in kilowatts. Positive values indicate
            charging, negative values indicate discharging.
          example: -3.4
        energy_remaining_kwh:
          type: number
          minimum: 0
          description: Estimated usable energy available, in kilowatt-hours.
          example: 8.3
        temperature_c:
          type: number
          description: >-
            Current battery pack temperature, in degrees Celsius. Where the
            source reports multiple module or cell temperatures, report the
            pack-level figure.
          example: 18.5
        backup_reserve_percent:
          type: number
          minimum: 0
          maximum: 100
          description: >-
            Percentage of capacity reserved for backup and unavailable for
            dispatch. Reported value: the desired value is set through [device
            settings](/energy-api/reference/device-settings/update).
          example: 20
        strategy:
          type: string
          enum:
            - SELF_POWER
            - SAVINGS
          description: >-
            Strategy the battery is operating under: `SELF_POWER` maximizes use
            of self-generated energy, `SAVINGS` charges when prices are low and
            discharges when high. Reported value; the desired value is set
            through device settings.
          example: SELF_POWER
        storm_mode_enabled:
          type: boolean
          description: >-
            Whether storm mode is enabled: the battery holds or increases charge
            ahead of severe weather. Reported value; the desired value is set
            through device settings.
          example: true
        storm_mode_active:
          type: boolean
          example: false
          description: >-
            `true` while the battery holds or builds charge for a forecast
            storm. Reported by the device. Distinct from the
            `storm_mode_enabled` setting, which says whether the feature is on.
            Energy held for a storm is not available for dispatch.
        export_rule:
          type: string
          enum:
            - BATTERY_OK
            - PV_ONLY
            - NEVER
          example: BATTERY_OK
          description: >-
            Export rule applied by the device; reported value of the
            `export_rule` setting: `BATTERY_OK`, `PV_ONLY` or `NEVER`.
        charge_from_grid_enabled:
          type: boolean
          example: true
          description: >-
            Whether the battery may charge from the grid; reported value of the
            `charge_from_grid_enabled` setting.
        grid_status:
          type: string
          enum:
            - ON_GRID
            - ISLANDED
            - UNKNOWN
          example: ON_GRID
          description: >-
            An islanded device is not dispatched; affected intervals are
            recorded as declined, not as a shortfall.


            | Value | Meaning |

            | :--- | :--- |

            | `ON_GRID` | Connected |

            | `ISLANDED` | On backup, disconnected |

            | `UNKNOWN` | Not reported |
    DeviceStateVehicle:
      title: DeviceStateVehicle
      type: object
      additionalProperties: false
      description: Operational state of an electric vehicle.
      properties:
        state_of_charge_percent:
          type: number
          minimum: 0
          maximum: 100
          description: >-
            Usable state of charge of the traction battery, as a percentage from
            0 to 100. Where the source distinguishes usable from nominal, report
            usable.
          example: 62
        charge_limit_percent:
          type: number
          minimum: 0
          maximum: 100
          description: Charge limit set on the vehicle, as a percentage from 0 to 100.
          example: 80
        energy_remaining_kwh:
          type: number
          minimum: 0
          description: >-
            Estimated usable energy available in the traction battery, in
            kilowatt-hours.
          example: 39.7
        plugged_in:
          type: boolean
          description: Whether the vehicle is connected to a charge point.
          example: true
        charging_state:
          type: string
          enum:
            - CHARGING
            - STOPPED
            - COMPLETE
            - DISCONNECTED
          example: CHARGING
          description: |-
            | Value | Meaning |
            | :--- | :--- |
            | `CHARGING` | Current flows |
            | `STOPPED` | Plugged in, paused |
            | `COMPLETE` | Plugged in, at charge limit |
            | `DISCONNECTED` | Nothing connected |
        time_departure:
          type: string
          format: date-time
          description: >-
            Expected departure time set on the vehicle, RFC 3339 in UTC;
            reported value of the `time_departure` setting. Smart charging plans
            against this deadline.
          example: '2026-02-01T07:30:00Z'
        range_km:
          type: number
          minimum: 0
          description: >-
            Estimated remaining range in kilometers, based on current
            consumption. Convert from miles at ingest.
          example: 180
        max_charging_power_kw:
          type: number
          minimum: 0
          nullable: true
          example: 7.4
          description: >-
            Charging power ceiling applied by the vehicle, in kW; reported value
            of the `max_charging_power_kw` setting. `null` when no ceiling is
            set.
    DeviceStateEvse:
      title: DeviceStateEvse
      type: object
      additionalProperties: false
      description: Operational state of an EV charge point.
      properties:
        plugged_in:
          type: boolean
          description: Whether a vehicle is connected to the charge point.
          example: true
        charging_state:
          type: string
          enum:
            - CHARGING
            - STOPPED
            - COMPLETE
            - DISCONNECTED
          example: CHARGING
          description: |-
            | Value | Meaning |
            | :--- | :--- |
            | `CHARGING` | Current flows |
            | `STOPPED` | Plugged in, paused |
            | `COMPLETE` | Plugged in, at charge limit |
            | `DISCONNECTED` | Nothing connected |
        power_kw:
          type: number
          description: >-
            Current power at the connector, in kilowatts. Positive values
            indicate delivery to the vehicle, negative values indicate the
            vehicle exporting through the charge point.
          example: 7.2
        max_charging_power_kw:
          type: number
          minimum: 0
          nullable: true
          example: 7.4
          description: >-
            Charging power ceiling applied by the charger, in kW; reported value
            of the `max_charging_power_kw` setting. `null` when no ceiling is
            set.
    DeviceStatePv:
      title: DeviceStatePv
      type: object
      additionalProperties: false
      description: Operational state of solar generation.
      properties:
        power_kw:
          type: number
          minimum: 0
          description: Current generation output, in kilowatts.
          example: 4.2
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Bearer token obtained from POST /auth/tokens.

````

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