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

# Settings

> Read and change persistent device configuration, such as a battery's reserve or an EV charger's power ceiling.

Settings are a device's standing configuration. Use them for limits the device should always respect, and [commands](/guides/push) for what it should do.

## Actions vs settings

If it makes sense with a time window, it's an action. "Charge from 6pm to 10pm" is an action. "Never discharge below 20%" is a setting.

| | Actions | Settings |
| - | - | - |
| Endpoint | `POST /battery/{deviceId}` | `POST /battery/{deviceId}/settings` |
| Response | `202`, runs asynchronously | `200`, synchronous |
| Scheduling | `start` / `end` | Not supported |
| Recorded | As an action, with webhooks | No action record |

Settings are available on batteries and EV chargers. The EV charger routes are `POST /ev-charger/{deviceId}` and `POST /ev-charger/{deviceId}/settings`.

## Read settings

Settings come back on the device read, with the current value and the bounds this device accepts.

```bash theme={null}
curl https://api.amps.ai/battery/device_abc123 \
  -H "x-api-key: $AMPS_API_KEY"
```

```json theme={null}
{
  "success": true,
  "data": {
    "id": "device_abc123",
    "settings": {
      "safety_reserve": { "value": 10, "unit": "percent", "min": 10, "max": 100 },
      "export_limit": { "value": 3000, "unit": "watts", "min": 0, "max": 30000 },
      "scheduler_enabled": { "value": false }
    }
  }
}
```

A setting is present only if the device offers it. `value` is `null` if the device hasn't reported it yet. A value the device reports in an unusable form, or outside its declared range, is left out. In live, `settings` appears on readings taken from the device; see [Freshness](/guides/pull#freshness).

## Change settings

Send only the settings you want to change. Numeric settings are `{ value, unit }`; on/off settings are `{ value }`.

```bash theme={null}
curl -X POST https://api.amps.ai/battery/device_abc123/settings \
  -H "x-api-key: $AMPS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "discharge_floor": { "value": 15, "unit": "percent" },
    "charge_ceiling": { "value": 95, "unit": "percent" }
  }'
```

```json theme={null}
{
  "success": true,
  "data": {
    "deviceId": "device_abc123",
    "updated": ["discharge_floor", "charge_ceiling"]
  }
}
```

Every setting in the request is validated before anything is written. If one fails, none are applied. In sandbox, the next read shows the new values.

## Battery settings

| Setting | Unit | Meaning |
| - | - | - |
| `safety_reserve` | `percent` | Lowest charge the battery will ever reach, even in a power cut. |
| `discharge_floor` | `percent` | Lowest charge during normal operation. |
| `charge_ceiling` | `percent` | Highest charge the battery will charge to. |
| `export_limit` | `watts` | Maximum power sent to the grid. |
| `max_charge_rate` | `amps` | Maximum charge current. |
| `max_discharge_rate` | `amps` | Maximum discharge current. |
| `scheduler_enabled` | | Whether the device's own scheduler is active. Read-only. |

## EV charger settings

| Setting | Unit | Meaning |
| - | - | - |
| `max_charge_rate` | `kw` | Maximum charging power the charger will draw. |
| `max_charge_current` | `amps` | The same ceiling, as current. |
| `cable_lock` | | Whether the cable stays locked to the charger. |
| `smart_charging` | | Whether the charger's own smart-charging schedule is active. When off, the charger doesn't start charges on its own. |

`max_charge_rate` and `max_charge_current` set one ceiling in two units. A charger that holds a single rate refuses both in one request with `UNSUPPORTED_SETTING_COMBINATION`. Send one.

The battery and EV charger `max_charge_rate` use different units: current in amps for batteries, power in kW for chargers. Always send the unit the read declares.

## Bounds

Percent settings allow 0 to 100 and rate settings start at 0, but each device can declare a narrower range. A battery might accept `discharge_floor` only from 10. Read `min` and `max` from the device before writing.

## Errors

| Code | Status | Cause |
| - | - | - |
| `EMPTY_SETTINGS` | 400 | The body has no settings. |
| `INVALID_REQUEST_BODY` | 400 | The body isn't a map of settings. |
| `DEVICE_NOT_CAPABLE` | 422 | The device doesn't offer this setting, or it's read-only, such as `scheduler_enabled`. `details.availableSettings` or `details.setting` says which. |
| `INVALID_SETTING_UNIT` | 422 | `unit` doesn't match the declared unit. |
| `INVALID_SETTING_VALUE` | 422 | Wrong value type. |
| `SETTING_OUT_OF_RANGE` | 422 | Outside the device's `min`/`max`, off its increment grid, or beyond a narrower limit the connected unit reports. |
| `UNSUPPORTED_SETTING_COMBINATION` | 422 | Two settings in the request set the same thing. |
| `CAPABILITY_PAUSED` | 503 | Amps has temporarily paused this setting. Retry with backoff. |
| `SETTINGS_STORE_UNAVAILABLE` | 503 | Settings are temporarily unavailable. Retry. |

Manufacturer errors can also come back directly, for example `SCHEDULER_ACTIVE` (409) on a battery or `VEHICLE_NOT_CONNECTED` (409) on a charger. See [Error codes](/guides/error-handling/error-codes).

## Next steps

<CardGroup cols={2}>
  <Card title="Capabilities" icon="list-check" href="/guides/capabilities">
    How devices declare what they accept.
  </Card>

  <Card title="Push" icon="arrow-up" href="/guides/push">
    Send commands to a device.
  </Card>

  <Card title="Error codes" icon="list" href="/guides/error-handling/error-codes">
    Every code, its status, and what triggers it.
  </Card>
</CardGroup>


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