Test the API — URLs, auth, Postman
Mint a token against the bundled realm and paste it into
curl, Postman, or Swagger UI — every door the hub serves, listed with the role it requires.
Every door the hub serves, which token opens it, and how to point Postman (or plain
curl) at it. URLs below are the self-host defaults; behind the
TLS façade everything lives on one
https origin, with Keycloak path-proxied under /realms/*.
The doors
| URL | Auth | What it is |
|---|---|---|
http://localhost:8080/q/health |
none | UP/DOWN with named checks — observability |
http://localhost:8080/q/metrics |
none | Prometheus metrics (block /q/* at the proxy on a public origin) |
http://localhost:8080/q/openapi |
none | the OpenAPI spec — what Postman imports |
http://localhost:8080/q/swagger-ui/ |
none | the try-it console, shipped in the packaged hub |
http://localhost:8080/app/ |
browser login | the métier PWA |
http://localhost:8080/api/rag/chat |
Bearer, lm_user |
the chat door — semantic or analytic, guards apply |
http://localhost:8080/api/entities/… |
Bearer, lm_user |
fused-entity reads, scope-bound — entities |
http://localhost:8080/api/views |
Bearer, lm_user |
saved-view discovery, scope-bound — views |
http://localhost:8080/api/platform/… |
Bearer, lm_integrator |
the whole integrator surface: connectors, validator, runs, apply |
http://localhost:8080/scim/v2/… |
SCIM bearer token | deprovisioning — SCIM |
http://localhost:8180/realms/lumnik |
— | Keycloak: the issuer, and the token endpoint below |
Roles ride in the JWT's groups claim; the catalog is on
Roles & permissions. A scope-bound user gets the
uniform 403 {"error":"scope not granted"} outside their métiers —
a feature, not a failure.
Mint a token
The bundled realm ships an integrator user (password: INTEGRATOR_PASSWORD in the
.env that up.sh generated) and a public CLI client, lm-cli, that allows the
password grant. In curl:
TOKEN=$(curl -s "http://localhost:8180/realms/lumnik/protocol/openid-connect/token" \
-d grant_type=password -d client_id=lm-cli \
-d username=integrator --data-urlencode password="$INTEGRATOR_PASSWORD" \
| jq -r .access_token)
# First authenticated smoke test:
curl -s http://localhost:8080/api/platform/health -H "Authorization: Bearer $TOKEN"
Tokens from the bundled realm live one hour (accessTokenLifespan: 3600) — mint
again when a call starts answering 401. Your own IdP may be stricter.
The same thing in Postman
On the collection's Authorization tab, choose OAuth 2.0 and fill:
| Field | Value |
|---|---|
| Grant type | Password Credentials |
| Access Token URL | http://localhost:8180/realms/lumnik/protocol/openid-connect/token |
| Client ID | lm-cli |
| Username / Password | integrator / the INTEGRATOR_PASSWORD from .env |
Get New Access Token → every request in the collection inherits the Bearer, and Postman re-mints it when it expires.
Import the whole API
Postman → Import → URL → http://localhost:8080/q/openapi. Postman reads the
OpenAPI spec straight from the running hub and builds the collection — every endpoint,
pre-filled. Set the collection auth as above and explore.
Prefer a browser? http://localhost:8080/q/swagger-ui/ is the same spec with a
try-it button — paste the token from Mint a token into its Authorize dialog.
Testing as a métier user, not an integrator
Everything above authenticates as integrator. To see the API the way a
scope-bound user sees it — the 403 scope not granted boundaries, the user chat
door — mint the token with that user's credentials instead; the mechanics are
identical. Scopes explains the
binding.