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

# Update battery device settings

> Write one or more writable settings on the device. Sparse: send only the settings you want to change. Read-only keys (e.g. `scheduler_enabled`) are rejected with 422 `READ_ONLY_SETTING`.



## OpenAPI

````yaml /openapi.json post /battery/{deviceId}/settings
openapi: 3.1.0
info:
  title: Amps.ai API
  description: >-
    Energy device management API for batteries, EV chargers, solar inverters,
    and HVAC systems
  version: '1.0'
  contact: {}
servers:
  - url: https://api.amps.ai
    description: Amps API
security: []
tags: []
paths:
  /battery/{deviceId}/settings:
    post:
      tags:
        - Battery
      summary: Update battery device settings
      description: >-
        Write one or more writable settings on the device. Sparse: send only the
        settings you want to change. Read-only keys (e.g. `scheduler_enabled`)
        are rejected with 422 `READ_ONLY_SETTING`.
      operationId: updateBatterySettings
      parameters:
        - name: deviceId
          required: true
          in: path
          description: The unique identifier for the battery device.
          schema:
            example: device_abc123
            type: string
      requestBody:
        required: true
        description: >-
          Sparse map of writable settings. At least one field is required. Each
          value uses the canonical `{ value, unit }` shape; unit must match the
          canonical setting.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatterySettingsUpdateRequest'
            examples:
              raiseSafetyReserve:
                summary: Raise the safety reserve to 20%
                description: >-
                  Sets the lowest SoC the battery will ever reach, even during a
                  power cut.
                value:
                  safety_reserve:
                    value: 20
                    unit: percent
              setDischargeFloor:
                summary: Set the normal-operation discharge floor to 15%
                value:
                  discharge_floor:
                    value: 15
                    unit: percent
              setChargeCeiling:
                summary: Cap the charge ceiling at 95%
                description: >-
                  Highest SoC the battery will charge to in normal operation.
                  Set below 100% to extend battery life.
                value:
                  charge_ceiling:
                    value: 95
                    unit: percent
              setExportLimitWatts:
                summary: Cap grid export at 3 kW
                value:
                  export_limit:
                    value: 3000
                    unit: watts
              setMaxChargeRateAmps:
                summary: Cap the charge rate at 25A
                value:
                  max_charge_rate:
                    value: 25
                    unit: amps
              setMaxDischargeRateAmps:
                summary: Cap the discharge rate at 25A
                value:
                  max_discharge_rate:
                    value: 25
                    unit: amps
              multiSettingUpdate:
                summary: Update multiple settings in one request
                description: >-
                  Sparse merge: only the listed keys change. Other settings are
                  untouched. Order in `updated[]` mirrors the request body
                  order.
                value:
                  discharge_floor:
                    value: 15
                    unit: percent
                  charge_ceiling:
                    value: 95
                    unit: percent
                  export_limit:
                    value: 3000
                    unit: watts
      responses:
        '200':
          description: >-
            Settings written. Response lists the canonical setting keys that
            changed.
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                  - meta
                properties:
                  success:
                    type: boolean
                    const: true
                    description: Always `true` for success responses.
                  data:
                    $ref: '#/components/schemas/BatterySettingsUpdateResponse'
                  meta:
                    $ref: '#/components/schemas/ResponseMeta'
              examples:
                singleSetting:
                  summary: One setting updated
                  value:
                    success: true
                    data:
                      deviceId: device_abc123
                      updated:
                        - safety_reserve
                    meta:
                      requestId: req_8a2Bf3kP
                      environment: sandbox
                      timestamp: '2026-06-02T12:00:00.000Z'
                      latencyMs: 12
                multipleSettings:
                  summary: Several settings updated atomically
                  value:
                    success: true
                    data:
                      deviceId: device_abc123
                      updated:
                        - discharge_floor
                        - charge_ceiling
                        - export_limit
                    meta:
                      requestId: req_8a2Bf3kP
                      environment: sandbox
                      timestamp: '2026-06-02T12:00:00.000Z'
                      latencyMs: 12
        '400':
          description: >-
            Invalid request body (not a key-value map, or empty `{}` after
            parsing). The device manufacturer can also refuse a well-formed
            request with this status (`BIND_NOT_SUPPORTED`, `COMMAND_FAILED`,
            `INVALID_OEM_PARAMETERS`, `INVALID_PARAMETERS`,
            `UNSUPPORTED_AUTH_PATH`, `UNSUPPORTED_CREDENTIAL_TYPE`). Every code
            at this status: `BIND_NOT_SUPPORTED`, `COMMAND_FAILED`,
            `EMPTY_SETTINGS`, `INVALID_OEM_PARAMETERS`, `INVALID_PARAMETERS`,
            `INVALID_REQUEST_BODY`, `UNSUPPORTED_AUTH_PATH`,
            `UNSUPPORTED_CREDENTIAL_TYPE`, `VALIDATION_ERROR`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                emptyBody:
                  summary: Body parsed as empty `{}` after validation
                  value:
                    success: false
                    error:
                      code: EMPTY_SETTINGS
                      message: At least one setting must be provided.
                    meta:
                      requestId: req_8iH1mTyY
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /battery/device_abc123/settings
                      latencyMs: 3
                malformedBody:
                  summary: Body is not a key-value map of canonical settings
                  value:
                    success: false
                    error:
                      code: INVALID_REQUEST_BODY
                      message: The request body is invalid.
                      details:
                        fields:
                          _errors:
                            - Expected object, received array
                        description: Request body must be a key-value map of settings.
                    meta:
                      requestId: req_9jI2nUzZ
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /battery/device_abc123/settings
                      latencyMs: 3
        '401':
          description: Invalid or missing API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                missingApiKey:
                  summary: No `x-api-key` header present
                  value:
                    success: false
                    error:
                      code: UNAUTHORIZED
                      message: Authentication is required.
                      details:
                        description: API key is required
                    meta:
                      requestId: req_8sW2dRtX
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /battery/device_abc123/settings
                      latencyMs: 2
        '403':
          description: >-
            Error codes: `FORBIDDEN`, `INVALID_MFA_CODE`, `MFA_REQUIRED`,
            `ACCOUNT_LOCKED`, `DEVICE_UNAUTHORIZED`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Device not found or access denied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                deviceNotFound:
                  summary: No device matches the ID for this customer
                  value:
                    success: false
                    error:
                      code: DEVICE_NOT_FOUND
                      message: No matching device was found for the supplied details.
                      details:
                        description: Device not found or access denied
                    meta:
                      requestId: req_5pH1cQbY
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /battery/device_unknown_999/settings
                      latencyMs: 5
        '409':
          description: >-
            The device manufacturer rejected the settings write because a
            schedule is running on the device (`SCHEDULER_ACTIVE`). Clear the
            schedule first. Every code at this status: `MODE_OVERRIDDEN`,
            `SCHEDULER_ACTIVE`, `SCHEDULER_FULL`, `VPP_LOCKED`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                schedulerActive:
                  summary: >-
                    The manufacturer rejected the settings write because a
                    schedule is running on the device. Clear the schedule first.
                  value:
                    success: false
                    error:
                      code: SCHEDULER_ACTIVE
                      message: >-
                        A schedule is currently active on the device and must be
                        cleared first.
                      details:
                        reason: foreign_scheduler_blocking_settings_write
                        description: >-
                          The device blocks settings writes while a schedule is
                          running on the device.
                    meta:
                      requestId: req_HpR9vCjJ
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /battery/device_abc123/settings
                      latencyMs: 412
        '410':
          description: 'Error codes: `DEVICE_OFFLINE`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: 'Error codes: `PAYLOAD_TOO_LARGE`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '415':
          description: 'Error codes: `UNSUPPORTED_MEDIA_TYPE`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            The request is well-formed but a setting can't be applied. Common
            codes: `UNSUPPORTED_SETTING` (key is not declared for this device),
            `READ_ONLY_SETTING` (key is read-only via the public API),
            `INVALID_SETTING_UNIT` (unit doesn't match the canonical),
            `INVALID_SETTING_VALUE` (wrong type), `SETTING_OUT_OF_RANGE`
            (outside the `min`/`max` this device declares, or outside a narrower
            limit the connected unit itself reports — a model rated to 22 kW can
            be an 11 kW unit, and the request is refused rather than quietly
            clamped). Every code at this status: `COMMAND_NOT_SUPPORTED`,
            `EXECUTION_NOT_SUPPORTED`, `INVALID_SETTING_UNIT`,
            `INVALID_SETTING_VALUE`, `INVALID_TIME_WINDOW`, `READ_ONLY_SETTING`,
            `SETTING_OUT_OF_RANGE`, `UNSUPPORTED_SETTING`,
            `UNSUPPORTED_SETTING_COMBINATION`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                unsupportedSetting:
                  summary: Setting key is not declared for this device
                  value:
                    success: false
                    error:
                      code: UNSUPPORTED_SETTING
                      message: The requested setting is not supported by this device.
                      details:
                        availableSettings:
                          - safety_reserve
                          - discharge_floor
                          - charge_ceiling
                          - export_limit
                          - max_charge_rate
                          - max_discharge_rate
                          - scheduler_enabled
                        description: >-
                          Setting 'mystery_knob' is not supported for this
                          device.
                    meta:
                      requestId: req_AkJ3oVaB
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /battery/device_abc123/settings
                      latencyMs: 7
                readOnlySetting:
                  summary: Caller tried to write a read-only key
                  value:
                    success: false
                    error:
                      code: READ_ONLY_SETTING
                      message: The requested setting is read-only.
                      details:
                        setting: scheduler_enabled
                        description: >-
                          Setting 'scheduler_enabled' is read-only and cannot be
                          written through the public API.
                    meta:
                      requestId: req_BlK4pWbC
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /battery/device_abc123/settings
                      latencyMs: 6
                settingOutOfRange:
                  summary: Value exceeds the canonical maximum
                  value:
                    success: false
                    error:
                      code: SETTING_OUT_OF_RANGE
                      message: >-
                        The supplied setting value is outside the supported
                        range.
                      details:
                        setting: safety_reserve
                        min: 0
                        max: 100
                        unit: percent
                        description: >-
                          Setting 'safety_reserve' value 120 exceeds maximum
                          100.
                    meta:
                      requestId: req_CmL5qXcD
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /battery/device_abc123/settings
                      latencyMs: 8
                wrongUnit:
                  summary: Unit on the value object does not match the canonical unit
                  value:
                    success: false
                    error:
                      code: INVALID_SETTING_UNIT
                      message: The supplied setting unit is invalid.
                      details:
                        setting: export_limit
                        expectedUnit: watts
                        receivedUnit: percent
                        description: >-
                          Setting 'export_limit' expects unit 'watts'; got
                          'percent'.
                    meta:
                      requestId: req_DnM6rYdE
                      timestamp: '2026-04-29T12:00:00.000Z'
                      path: /battery/device_abc123/settings
                      latencyMs: 7
        '429':
          description: 'Error codes: `RATE_LIMITED`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: 'Error codes: `INTERNAL_ERROR`, `UNKNOWN_ERROR`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '502':
          description: 'Error codes: `NETWORK_ERROR`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: >-
            Error codes: `SERVICE_UNAVAILABLE`, `NOT_YET_AVAILABLE`,
            `SIMULATED_FAILURE`, `OEM_CIRCUIT_OPEN`,
            `SETTINGS_STORE_UNAVAILABLE`. `SERVICE_UNAVAILABLE` is temporary:
            retry with exponential backoff. `NOT_YET_AVAILABLE` is not: Amps has
            not switched this route on yet, so retrying returns the same answer
            until it does.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '504':
          description: 'Error codes: `TIMEOUT`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - api-key: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl --request POST \
              --url 'https://api.amps.ai/battery/device_abc123/settings' \
              --header 'x-api-key: amps_sk_test_xxxxxxxxxxxxxxxxxxxxxxxx' \
              --header 'content-type: application/json' \
              --data '{
                "safety_reserve": {
                  "value": 20,
                  "unit": "percent"
                }
              }'
        - lang: javascript
          label: Node
          source: >-
            const response = await
            fetch('https://api.amps.ai/battery/device_abc123/settings', {
              method: 'POST',
              headers: {
                'x-api-key': 'amps_sk_test_xxxxxxxxxxxxxxxxxxxxxxxx',
                'content-type': 'application/json',
              },
              body: JSON.stringify({
                "safety_reserve": {
                  "value": 20,
                  "unit": "percent"
                }
              }),
            });


            const data = await response.json();
        - lang: python
          label: Python
          source: |-
            import requests

            url = 'https://api.amps.ai/battery/device_abc123/settings'
            headers = {
                'x-api-key': 'amps_sk_test_xxxxxxxxxxxxxxxxxxxxxxxx',
                'content-type': 'application/json',
            }
            payload = {
                "safety_reserve": {
                    "value": 20,
                    "unit": "percent",
                },
            }

            response = requests.post(url, headers=headers, json=payload)
            data = response.json()
components:
  schemas:
    BatterySettingsUpdateRequest:
      type: object
      properties:
        safety_reserve:
          $ref: '#/components/schemas/Quantity'
          description: >-
            The lowest state-of-charge the battery will ever reach, even during
            a power cut. (unit: `percent`, min: 0, max: 100)
        discharge_floor:
          $ref: '#/components/schemas/Quantity'
          description: >-
            The lowest state-of-charge the battery will reach during normal
            operation. (unit: `percent`, min: 0, max: 100)
        charge_ceiling:
          $ref: '#/components/schemas/Quantity'
          description: >-
            The highest state-of-charge the battery will charge to. (unit:
            `percent`, min: 0, max: 100)
        export_limit:
          $ref: '#/components/schemas/Quantity'
          description: >-
            Maximum power the battery can send back to the grid. (unit: `watts`,
            min: 0)
        max_charge_rate:
          $ref: '#/components/schemas/Quantity'
          description: >-
            Maximum rate the battery will charge at. (unit: `amps`, min: 0, max:
            1000)
        max_discharge_rate:
          $ref: '#/components/schemas/Quantity'
          description: >-
            Maximum rate the battery will discharge at. (unit: `amps`, min: 0,
            max: 1000)
      description: >-
        Sparse map of writable settings. At least one field is required. Unknown
        or read-only keys are rejected with `UNSUPPORTED_SETTING`.
      examples:
        - safety_reserve:
            value: 20
            unit: percent
        - discharge_floor:
            value: 15
            unit: percent
          charge_ceiling:
            value: 95
            unit: percent
        - export_limit:
            value: 3000
            unit: watts
      title: Battery Settings Update
    BatterySettingsUpdateResponse:
      type: object
      properties:
        deviceId:
          type: string
          description: The battery device the settings were written to.
        updated:
          type: array
          items:
            type: string
          description: >-
            Canonical setting keys that the request changed. Order mirrors the
            request body order.
      required:
        - deviceId
        - updated
      description: >-
        Acknowledgement of a settings write. `updated` lists the canonical
        setting keys that changed; OEMs that fire-and-forget will still echo the
        keys. A device holds only the values its own hardware steps to, so a
        written value can land on the nearest step it can deliver. Read the
        settings back to see what it holds. A value the device cannot deliver at
        all is refused rather than quietly adjusted.
      title: Battery Settings Update
    ResponseMeta:
      type: object
      title: Response Meta
      description: >-
        Metadata attached to every response: the request identifier, the serving
        environment, the build timestamp, and the server-side latency.
      required:
        - environment
        - timestamp
        - latencyMs
      properties:
        requestId:
          description: >-
            Unique request identifier. Echoes the `x-request-id` header when
            present; otherwise generated server-side.
          type: string
        environment:
          type: string
          description: The environment that served the request (`sandbox` or `live`).
        timestamp:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the response was built.
        latencyMs:
          type: integer
          description: Server-side processing time in milliseconds.
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Always `false` for error responses.
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - INVALID_CREDENTIALS
                - INVALID_API_KEY
                - INVALID_MFA_CODE
                - MFA_REQUIRED
                - ACCOUNT_LOCKED
                - UNSUPPORTED_CREDENTIAL_TYPE
                - DEVICE_NOT_FOUND
                - DEVICE_OFFLINE
                - DEVICE_UNAUTHORIZED
                - NO_DEVICES_FOUND
                - COMMAND_FAILED
                - COMMAND_NOT_SUPPORTED
                - EXECUTION_NOT_SUPPORTED
                - MODE_OVERRIDDEN
                - VPP_LOCKED
                - INVALID_PARAMETERS
                - INVALID_OEM_PARAMETERS
                - INVALID_TIME_WINDOW
                - BIND_NOT_SUPPORTED
                - SCHEDULER_ACTIVE
                - SCHEDULER_FULL
                - UNSUPPORTED_AUTH_PATH
                - SETTING_OUT_OF_RANGE
                - NETWORK_ERROR
                - RATE_LIMITED
                - SERVICE_UNAVAILABLE
                - TIMEOUT
                - NOT_YET_AVAILABLE
                - SIMULATED_FAILURE
                - UNKNOWN_ERROR
                - VEHICLE_NOT_CONNECTED
                - SESSIONS_NOT_SUPPORTED
                - CREDENTIAL_NOT_FOUND
                - OEM_CIRCUIT_OPEN
                - INVALID_OEM_RESPONSE
                - COMMAND_NOT_APPLIED
                - STALE_ACTION
                - DEFERRED_SCHEDULE_FAILED
                - UNROUTABLE_ACTION_TYPE
                - UNAUTHORIZED
                - EXPIRED_TOKEN
                - FORBIDDEN
                - INSUFFICIENT_PERMISSIONS
                - LIVE_ACCESS_DISABLED
                - VALIDATION_ERROR
                - INVALID_INPUT
                - INVALID_REQUEST_BODY
                - EMPTY_SETTINGS
                - PAYLOAD_TOO_LARGE
                - UNSUPPORTED_MEDIA_TYPE
                - NOT_FOUND
                - METHOD_NOT_ALLOWED
                - CONFLICT
                - CONFLICT_IN_EXECUTION
                - GONE
                - RATE_LIMIT_EXCEEDED
                - INTERNAL_ERROR
                - NOT_IMPLEMENTED
                - BAD_GATEWAY
                - GATEWAY_TIMEOUT
                - DEVICE_TYPE_MISMATCH
                - CONSENT_REVOKED
                - DEVICE_OVERAGE
                - SETTINGS_STORE_UNAVAILABLE
                - ACTION_NOT_FOUND
                - DIRECT_ACTION_UNSUPPORTED
                - UNSUPPORTED_ACTION
                - UNSUPPORTED_MODE
                - UNSUPPORTED_PARAMETER
                - UNSUPPORTED_PARAMETER_COMBINATION
                - UNSUPPORTED_UNIT
                - PARAMETER_OUT_OF_RANGE
                - START_IN_PAST
                - START_OUT_OF_RANGE
                - START_OFFSET_NOT_ACCEPTED
                - START_INVALID_FORMAT
                - START_NONEXISTENT_WALL_CLOCK
                - TIMEZONE_UNRESOLVED
                - INVALID_TIMEZONE
                - ACTION_NOT_CANCELLABLE
                - STRATEGY_NOT_SUPPORTED
                - UNSUPPORTED_SETTING
                - UNSUPPORTED_SETTING_COMBINATION
                - READ_ONLY_SETTING
                - INVALID_SETTING_UNIT
                - INVALID_SETTING_VALUE
                - NO_OP
                - NO_OVERRIDE
                - AVAILABILITY_ENV_UNSUPPORTED
                - UNSUPPORTED_COMBINATION
              description: >-
                Machine-readable error code (e.g. `VALIDATION_ERROR`,
                `CONFLICT`, `UNSUPPORTED_MODE`). Stable across releases; safe to
                switch on.
            message:
              type: string
              description: Human-readable error message.
            details:
              description: >-
                Structured context for the error: which fields were invalid,
                which actions conflicted, which capabilities the device
                declares. Shape varies by error code.
              type: object
              properties: {}
              additionalProperties: {}
          required:
            - code
            - message
          description: Error envelope.
        meta:
          type: object
          properties:
            requestId:
              description: >-
                Unique request identifier. Echoes the `x-request-id` header when
                present; otherwise generated server-side.
              type: string
            timestamp:
              type: string
              description: ISO 8601 timestamp when the error response was built.
            path:
              type: string
              description: Request path that produced the error.
            latencyMs:
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
              description: Server-side processing time in milliseconds.
          required:
            - timestamp
            - path
            - latencyMs
          description: Request metadata.
      required:
        - success
        - error
        - meta
      title: Error Response
      description: >-
        Uniform error response. The `error.code` identifies the failure,
        `error.message` carries a human-readable explanation, and
        `error.details` carries structured context (failed fields, conflicting
        action IDs, supported capabilities) where relevant.
    Quantity:
      type: object
      properties:
        value:
          type: number
          description: Numeric magnitude.
        unit:
          type: string
          enum:
            - percent
            - kw
            - watts
            - kwh
            - amps
            - volts
            - hours
            - minutes
            - celsius
            - fahrenheit
          description: >-
            Unit of measure. Closed set so consumers can switch exhaustively at
            the type layer.
      required:
        - value
        - unit
      title: Quantity
      description: >-
        Self-describing numeric value with its unit. `value` is the magnitude,
        `unit` names one of the canonical units.
  securitySchemes:
    api-key:
      type: apiKey
      in: header
      name: x-api-key

````