REST API
GEM exposes a REST API for configuration reads/writes and for issuing commands. It's mounted under /api and is enabled by rest_api: true in gem.json.
Authentication
Obtain a session token, then send it on subsequent requests.
| Method | Path | Auth | Purpose |
|---|---|---|---|
POST | /api/token | credentials | Obtain a session token. |
POST | /api/logout | token | Revoke the current token. |
GET | /api/me | token | Current user identity and roles. |
GET | /api/health | none | Liveness check (unauthenticated). |
GET | /api/version | none | Controller version (public). |
Requests other than the public ones require a valid token; without one the API returns 401 unauthorized.
Commands — /api/control/:action
POST only (other methods return 405). Two actions are supported, each gated by the matching RBAC permission:
| Action | Body | Maps to |
|---|---|---|
command | a command payload ({ device, zone, action, level, … }) | GemServer.command(body) |
macro | a macro reference ({ macro_id } or { macro }) | GemServer.macro(body) |
curl -X POST https://<host>/api/control/command \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"zone": 12, "action": "on", "level": 100}'
A caller lacking the command / macro permission gets 403.
Data — /api/data/:entity
CRUD over configuration entities (device, zone, macro, …).
GET— read. Query-string parameters become awherefilter (numeric-looking values are coerced to numbers). Requires thequerypermission.POST/PUT/DELETE— write. The JSON body carries the payload.
# all zones in subsystem 11
curl "https://<host>/api/data/zone?subsystem_id=11" \
-H "Authorization: Bearer <token>"
Errors
| Status | Meaning |
|---|---|
400 | Malformed/invalid body. |
401 | Missing or invalid session token. |
403 | Authenticated but the role denies this action. |
405 | Wrong method (e.g. non-POST to /api/control). |
:::note The WebSocket API is the richer surface REST covers data CRUD and commands. For real-time state, subscriptions, attributes, and the full set of operations, use the WebSocket API — both are gated by the same RBAC actions. :::