Call a gateway's HTTP API without holding that gateway's credentials.
The proxy authenticates upstream as the gateway's master_rest user, and
authorises you by asking the CMS whether you have access to the facility behind it.
The proxy has no accounts of its own. Log into the CMS and use that token:
TOKEN=$(curl -s https://app.smartrplace.de/api/users/login \
-H 'Content-Type: application/json' \
-d '{"email":"you@smartrplace.de","password":"…"}' | jq -r .token)
Auth-Token header, not
Authorization: Bearer — its OpenAPI spec declares a bearer scheme it does
not implement. The proxy accepts either form.curl -H "Auth-Token: $TOKEN" \
https://gateway-access.smartrplace.de/gw/jakob-sozien/apimobile/monitoring/datapoints
The gateway may be addressed three ways, all equivalent:
| Form | Example |
|---|---|
| subdomain | /gw/jakob-sozien/… |
| bare gateway id | /gw/19106/… |
gw-prefixed id | /gw/gw19106/… |
Everything after the gateway is the upstream path and is forwarded as written, percent-encoding intact, together with the query string.
If holding a CMS token is awkward, exchange the credentials for a session token — the proxy forwards them to the CMS and never stores the password:
TOKEN=$(curl -s https://gateway-access.smartrplace.de/auth/login -H 'Content-Type: application/json' -d '{"email":"you@smartrplace.de","password":"…"}' | jq -r .token)
# then use it exactly like a CMS token, in Auth-Token
curl -H "Auth-Token: $TOKEN" https://gateway-access.smartrplace.de/gw/19106/apimobile/monitoring/datapoints
curl -X POST -H "Auth-Token: $TOKEN" https://gateway-access.smartrplace.de/auth/logout # when done
Sessions last 8 hours. They grant nothing extra: the identity behind one is re-checked with the CMS on every request, so access revoked there takes effect within minutes, not at the end of the session.
| Header | For |
|---|---|
Auth-Token: <CMS token> |
Recommended. Nothing is stored here; the CMS's 24 h expiry applies. |
Authorization: Bearer <CMS token> |
The same token, for clients that dislike custom headers. |
X-Service-Token: <token> |
Internal tooling. Named, and scoped to an explicit gateway list — no CMS user needed. |
CMS super admins, callers with a facility-level role at the
gateway's facility, and service tokens scoped to it. Tenancy-level callers — tenant,
employee, WEG owner — are refused even though the CMS grants them access to that
facility: master_rest is exempt from the gateway's own per-room
permission checks, so a forwarded response covers the whole site, not one flat.
Use GET /me to see how your credentials are read, and
GET /me/gateways for the gateways you can expect to reach (a hint list —
the real decision is made per request against the CMS).
| Endpoint | |
|---|---|
GET /gw/{gateway}/{path} | the proxy itself |
GET /me | your identity as the proxy resolves it |
GET /me/gateways | gateways you can expect to reach |
GET /health |
liveness, credential-store state, effective policy, stale credentials |
POST /auth/login | credentials → session token |
POST /auth/logout | invalidate a session token |
GET /metrics |
counters (super admins and service tokens only) |
Every error has the same shape — {"error": code, "detail": sentence} —
so a client can branch on one field no matter which layer refused.
| Status | error | Meaning |
|---|---|---|
| 401 | unauthenticated |
no credentials, or the CMS rejected them |
| 403 | no_cms_access, tenancy_level_role,
no_facility_role, service_token_scope |
the proxy's decision: you may not |
| 403/400 | path_not_allowed |
outside the allowlist, or a smuggled path separator |
| 404 | unknown_gateway |
no such gateway, or no credentials held for it — deliberately indistinguishable |
| 405 | — | method not proxied |
| 502 | gateway_unreachable, gateway_timeout,
gateway_auth_failed, response_too_large |
the gateway failed, not you. gateway_auth_failed means the
proxy's stored master_rest password is stale |
| 502 | cms_unavailable |
no access decision could be made — never reported as a denial |
| 429 | rate_limited, too_many_in_flight |
slow down — both carry Retry-After |
| 503 | gateway_busy,
credentials_unavailable |
too many in-flight requests for that gateway / no credential store |
GET, HEAD./apimobile/monitoring/.Retry-After. Failed authentications are limited separately, by address.gateway_busy — gateways are
small boxes running live control loops.X-Proxy-Cache response header says hit, miss or
bypass.