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.
Overview
To charge a battery between two timestamps, push a charge action with both start and end. The action fires at start and reverts the battery at end, so you can ride a cheap-rate tariff overnight without touching the API again.
A cheap-rate window is the most common reason to write a windowed charge: an Octopus Agile dip, a Cosy off-peak slot, a tariff window the customer’s app already knows about. The platform fires the command at the start, reverts the device at the end, and webhook payloads land at each transition so the customer’s app reflects what actually happened.
Before you push, check that the battery supports windowed execution. Look for windowed in commands.charge.execution on a GET /battery/{deviceId}.
Step 1: Check capability before pushing
Read the device and inspect the commands.charge.execution array.
curl -X GET https://api.amps.ai/battery/dev_abc123 \
-H "x-api-key: sk_live_abc123xyz" \
-H "Content-Type: application/json"
{
"id" : "dev_abc123" ,
"vendor" : "foxess" ,
"sync" : { "available" : true , "lastPulledAt" : "2026-05-07T19:42:11.000Z" },
"metadata" : { "model" : "FoxESS H1-5.0-E" , "source" : "cache" , "cacheType" : "normal" },
"state" : {
"status" : "idle" ,
"capacity" : 10.4 ,
"level" : 67 ,
"chargeRate" : 0 ,
"dischargeLimit" : 10
},
"commands" : {
"charge" : {
"type" : "set_operation_mode" ,
"parameters" : {
"target" : { "unit" : "percent" , "min" : 10 , "max" : 100 },
"power" : { "unit" : "kw" , "min" : 0 , "max" : 5 }
},
"execution" : [ "windowed" ]
}
},
"settings" : { "charge_ceiling" : { "value" : 100 , "unit" : "percent" } }
}
If execution includes windowed, you are clear to push.
Step 2: Push a windowed charge
Send command: "charge" with start, end, and a target. Timestamps are absolute ISO 8601 with timezone. Parameters take the canonical { value, unit } shape.
curl -X POST https://api.amps.ai/battery/dev_abc123 \
-H "x-api-key: sk_live_abc123xyz" \
-H "Content-Type: application/json" \
-d '{
"action": {
"command": "charge",
"start": "2026-05-08T22:00:00Z",
"end": "2026-05-09T05:00:00Z",
"parameters": {
"target": { "value": 90, "unit": "percent" },
"power": { "value": 3, "unit": "kw" }
}
}
}'
const res = await fetch ( "https://api.amps.ai/battery/dev_abc123" , {
method: "POST" ,
headers: {
"x-api-key" : process . env . AMPS_API_KEY ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({
action: {
command: "charge" ,
start: "2026-05-08T22:00:00Z" ,
end: "2026-05-09T05:00:00Z" ,
parameters: {
target: { value: 90 , unit: "percent" },
power: { value: 3 , unit: "kw" },
},
},
}),
});
const { actionId , state } = await res . json ();
import os, requests
res = requests.post(
"https://api.amps.ai/battery/dev_abc123" ,
headers = {
"x-api-key" : os.environ[ "AMPS_API_KEY" ],
"Content-Type" : "application/json" ,
},
json = {
"action" : {
"command" : "charge" ,
"start" : "2026-05-08T22:00:00Z" ,
"end" : "2026-05-09T05:00:00Z" ,
"parameters" : {
"target" : { "value" : 90 , "unit" : "percent" },
"power" : { "value" : 3 , "unit" : "kw" },
},
}
},
)
body = res.json()
action_id = body[ "actionId" ]
You get back 202 Accepted. The action stays in scheduled state until the window opens.
{
"actionId" : "act_pending_001" ,
"state" : "scheduled" ,
"type" : "battery:set_operation_mode" ,
"createdAt" : "2026-05-07T20:11:42.000Z" ,
"start" : "2026-05-08T22:00:00.000Z"
}
Step 3: Track the action
Actions move through scheduled to acknowledged to completed. Poll the action endpoint, or subscribe to webhooks for push.completed and push.failed.
curl -X GET https://api.amps.ai/actions/act_pending_001 \
-H "x-api-key: sk_live_abc123xyz"
{
"id" : "act_pending_001" ,
"deviceId" : "dev_abc123" ,
"type" : "battery:set_operation_mode" ,
"state" : "scheduled" ,
"parameters" : {
"mode" : "charge" ,
"target" : { "value" : 90 , "unit" : "percent" },
"power" : { "value" : 3 , "unit" : "kw" }
},
"result" : null ,
"errorCode" : null ,
"errorMessage" : null ,
"createdAt" : "2026-05-07T20:11:42.000Z" ,
"updatedAt" : "2026-05-07T20:11:42.000Z" ,
"acknowledgedAt" : null ,
"completedAt" : null ,
"start" : "2026-05-08T22:00:00.000Z" ,
"end" : "2026-05-09T05:00:00.000Z"
}
When the window opens, the command dispatches to the OEM. acknowledgedAt populates and state advances to acknowledged. On success, state reaches completed and a push.completed webhook fires.
Step 4: Cancel before the window opens
Plans change. Cancel the action while it is still scheduled.
curl -X POST https://api.amps.ai/actions/act_pending_001/cancel \
-H "x-api-key: sk_live_abc123xyz"
The response echoes the action with state: cancelled.
What next
Discharge during peak Mirror this recipe to force-discharge during expensive windows.
Subscribe to webhooks Receive push.completed events instead of polling.
Handle conflicts What happens when an action is already in flight.
Scheduling concepts The semantic background to start, end, and execution shapes.