The Amps API is built so an agent never needs device-specific code. Every read response carries the contract for the next write. Every error envelope carries enough structure for the agent to fix its own request. The same shape that drives reasoning drives rendering. This page is for integrators wiring an agent at the API layer or building a UI on top of it. The patterns work against the deployed REST API and the Documentation MCP, and will work against the Execution MCP when it ships.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.
Capabilities ship with state
There is no separate/capabilities endpoint. A GET /battery/{deviceId} returns the device’s current state and its full capability declaration in the same body:
commands.charge.parameters.power on the read maps directly to action.parameters.power on the write. One read tells the agent which commands fire, which parameters apply with which units and bounds, and which execution shapes (immediate, scheduled, windowed) the device can run.
See capabilities for the full presence-based contract: a key is present iff the device supports it. There is no supported: boolean middle state.
The Quantity envelope
Every numeric parameter is aQuantity: an object with both value and unit. The unit travels with the value, so 80 is never ambiguous between percent, kilowatts, or amps:
percent, kw, watts, kwh, amps, volts, hours, minutes, celsius, fahrenheit. The enum is the shape that lets a UI component switch on unit at the type layer, so a numeric scalar with unit: "percent" renders as a state-of-charge ring while unit: "kw" renders as a power gauge with kilowatt scale. Same component shape, different visual output, no per-device branching.
Build the next request from the read
The agent’s loop:GET /battery/{deviceId}(orget_batteryvia the Execution MCP)- Inspect
commandsto choose a verb (charge,discharge,auto.balanced, etc.) - Inspect
commands.<verb>.parametersto know which parameters apply, with what units and bounds - Inspect
commands.<verb>.executionto chooseimmediate,scheduled, orwindowed - Build the body and
POST /battery/{deviceId}
target in percent or in kwh. It reads, it builds. The same code works across every device family that follows the canonical model.
Errors carry the contract
A 422 rejection ships a structureddetails block the agent can act on. The most powerful field is deviceCapabilities: a snapshot of the device’s current capability declaration, in the same shape the GET returns.
details.deviceCapabilities, drops the unsupported parameter, and retries. One round trip, no human intervention. The same pattern fires for UNSUPPORTED_UNIT, UNSUPPORTED_MODE, and EXECUTION_NOT_SUPPORTED. See error envelope for the full code list.
This is what makes the API safe for an agent to drive autonomously. The error envelope is not a dead end. It is the next read.
Conflict envelopes are self-describing too
When a push collides with an active action and the request did not declareonConflict, the API returns 409 CONFLICT with the conflicting action IDs in details.conflictingActionIds. The agent reads, decides whether to cancel_and_replace or queue_after, and re-posts with onConflict set. Same pattern: rejection plus enough structure to fix the next call.
See conflict resolution for the strategies and trade-offs.
What this unlocks
A single agent loop, one set of UI primitives, every device family in the canonical model. The agent’s reasoning code does not branch per OEM. The UI components do not branch per OEM. Every device that joins the model gets the same tooling for free. This is what “self-describing” delivers in practice. Not a marketing line. A shape choice that makes agents possible.What next
Dynamic UI rendering
How the same envelope drives generative UI. Shape-to-primitive mapping, streaming placeholders.
Confirmation gates
Why destructive tool calls do not free-fire from the model.
Capabilities
The presence-based capability contract in full.
Error envelope
The full code taxonomy and the
details shapes the agent can act on.