/openapi/openapi.json.
Paste this page into an agent’s system prompt, or wire the MCP server, to ground it in the vocabulary the API enforces rather than the one a manufacturer’s app uses.
Commands
Five commands. Two are direct imperatives; three hand timing to the charger’s own optimiser.charge Begin or resume charging the connected vehicle. Rate-capped by power or current, stopped by target or energy. The only command that takes a window.
idle Pause charging, holding the session. The canonical stop verb, same as on a battery and a thermostat.
auto.charge_tariff Charge during the cheapest hours of the tariff the home owner configured at the manufacturer.
auto.charge_surplus_only Charge from on-site generation the home is not using. Pauses when that surplus runs out, so the car may not fill.
auto.charge_surplus_first Use that surplus first, top up from the grid. The car fills; some of it is imported.
There is no discharge. Vehicle-to-home and vehicle-to-grid export sit outside the command surface, though the read still reports them (see discharging below).
A command’s presence in the device’s commands map means supported. Absence means rejected with 422 UNSUPPORTED_MODE, which lists the supported set.
Parameters
Every numeric parameter is aQuantity: { value, unit }.
power Rate cap in kilowatts. Unit: kw.
current The same rate cap in amperes, the native lever on most chargers. Unit: amps.
target Stop when the vehicle reaches this state of charge. Unit: percent. Only chargers that can read the car’s level declare it.
energy Stop after this much energy has been delivered in the session. Unit: kwh. What a charger that cannot see inside the car declares instead.
power and current cap the same rate, so supplying both returns 422 UNSUPPORTED_PARAMETER_COMBINATION with details.conflictingParameters. Send one.
idle and all three auto.* modes take no parameters. A parameter on a strategy reads as a ready-by goal, which needs a planner the platform does not have, so it is refused with 422 UNSUPPORTED_PARAMETER rather than answered with a mode change.
Execution shapes
A strategy is never windowed. The window machinery turns a mode on at
start and sends idle at end, which would stop the charge at the moment the driver asked for the car to be ready. A strategy runs until another command replaces it. A window on one returns 422 EXECUTION_NOT_SUPPORTED.
start and end are plant-local wall-clock ISO 8601 (YYYY-MM-DDTHH:MM:SS), no offset and no Z. Responses echo them as absolute UTC. Full contract on canonical actions.
State
Three fields are always present. Every reading is presence-based: a key is absent because this charger does not report that reading, never because the value is zero.status One of available, charging, discharging, scheduled, error, offline.
isConnected Whether a vehicle is plugged in.
isCharging Whether power is flowing to the vehicle right now. false during an export.
currentPower Optional. Kilowatts, signed: positive charging the car, negative exporting from it. Sum across chargers as a signed number. A charger drawing nothing reports 0; absent means this brand’s API carries no power reading at all.
maxCurrent Optional. Maximum current the charger can deliver, in amps. Absent when the charger does not report its applied ceiling.
powerRateLimit Optional. Configured maximum charging power, in kW. Absent for the same reason as maxCurrent.
sessionEnergy Optional. Energy delivered so far in the open session, in kWh. Resets each plug-in.
phases Optional. Supply phases in use, 1 to 3.
voltage Optional. Supply voltage in volts.
notChargingReason Optional. Why a plugged-in car is not drawing: vehicle, charger, authorization, schedule, or unknown. Absent means the charger said nothing; unknown means it reported a pause and would not name the cause. Only authorization is actionable by the driver.
activeControlMode Optional. The canonical mode the charger reports it is running under, drawn from the five commands. isCharging says whether energy is moving; this says which regime put it that way.
sessions Whether this charger reports charging-session history. Sits beside state, not inside it: it describes the charger’s API surface, not a reading. false means GET /ev-charger/{deviceId}/sessions answers 422 SESSIONS_NOT_SUPPORTED.
discharging is not a charging state. A charger exporting from the car reports status: "discharging" with a negative currentPower and isCharging: false.
vehicle sits beside state, not inside it. It is { id, links.self } pointing at the car this charger is filling, or null when the platform cannot tell which car it is. A pointer, not a copy: read the state of charge on the vehicle resource.
Settings
Persistent configuration, written throughPOST /ev-charger/{deviceId}/settings as a sparse map. Fire-and-forget, no time window, no conflict resolution.
max_charge_rate Standing ceiling the charger draws under. Unit: kw.
max_charge_current The same ceiling in amperes. Unit: amps.
cable_lock Whether the cable stays locked to the charger. Boolean.
max_charge_rate and max_charge_current are one ceiling in two units. A charger holding a single rate register refuses the pair with 422 UNSUPPORTED_SETTING_COMBINATION and names them in details.conflictingSettings.
Setting versus parameter. A power parameter caps one session. max_charge_rate is the ceiling the charger stays under whatever anyone asks next, including a session started from the manufacturer’s own app. Site constraint, setting. Session constraint, parameter.
Charging sessions
GET /ev-charger/{deviceId}/sessions. limit (1-50, default 10) and offset pagination, newest first.
Pin the window when you page. Each page reports the window it was cut from as window. Send its to back as the to parameter on every later page: the list grows at the head, so an unpinned walk lets a session that starts mid-walk push a row past you.
id Amps identifier, opaque and unique across every charger, safe as a primary key. Not the manufacturer’s session number.
status active or completed. An active session carries no endedAt and no endReason.
startedAt / endedAt Absolute UTC instants, not wall-clock.
energyDelivered { value, unit: "kwh" }. Never negative.
measurement How that figure was produced: metered (read off a cumulative register), oem_reported (the manufacturer computed it), or inferred (integrated from power samples). Provenance is not accuracy. No value is a settlement-grade guarantee.
endReason unplugged, vehicle_finished, stopped, power_lost, fault, or unknown. Absent when the charger gives no reason.
Filters. from/to (ISO 8601 UTC, defaulting to the last 30 days) select sessions overlapping the window, not contained by it. status narrows to running or finished.
Session history depends on the charger.
sessions on the device read says whether this one has it. false means the manufacturer records none and this endpoint answers 422 SESSIONS_NOT_SUPPORTED. Permanent, so read the flag rather than the refusal.Conflict resolution
One non-terminal action per charger.conflictStrategies on the read declares which onConflict values this charger accepts.
cancel_and_replace Cancel the conflicting action, run the new one. Works everywhere.
queue_after Defer the new action’s start to the conflict’s end. Needs the conflicting action to have an end, so it queues behind a windowed charge and not behind an open-ended strategy: that returns 409 with reason: conflicting_action_not_windowed.
An action already dispatched returns 409 CONFLICT_IN_EXECUTION with an empty strategy list. Wait, then re-submit.
Refusals specific to this surface
The full taxonomy lives on error envelope and device error codes.
Worked walkthroughs
Smart charging an EV
Windows, strategies, and reading back which one is running.
Read charging sessions
History, pagination, and measurement provenance.
Cap an EV charger's power
The standing ceiling and the settings surface.
Battery cheat sheet
Lifecycle, environments, and the shared vocabulary.