Org
Org-wide visibility: a single usage rollup and the tamper-evident audit trail. Both routes are admin-gated. See Usage and audit for the CLI-rendered table views of these same responses.
GET /v1/org/usage — usage rollup
Auth: admin.
$ curl -s https://api.stagdb.com/v1/org/usage -H "Authorization: Bearer $TOKEN"
Response 200 OK
{
"quota": {"max_per_user": 3, "max_per_org": 30, "active_in_org": 14},
"users": [
{"email": "[email protected]", "display_name": "Alex Park", "role": "admin", "status": "active", "active": 1, "total": 4},
{"email": "[email protected]", "display_name": "Dana Lin", "role": "user", "status": "active", "active": 2, "total": 9}
],
"goldens": [
{"name": "prod-pg16", "latest_version": 3, "shared": true, "active": 11, "total": 40}
],
"clusters": [
{"name": "prod", "health": "connected", "last_seen": "2026-07-19T08:12:41Z", "active_instances": 14}
],
"pools": [
{"golden": "prod-pg16", "warm": 5, "target": 5}
],
"imports": {
"total": 3,
"succeeded": 3,
"failed": 0,
"last_finished_at": "2026-07-18T22:10:04Z"
}
}
One call, six sections — quota, users, goldens, clusters, pools,
imports. This is the same data available piecemeal from GET /v1/org/quota, GET /v1/users, GET /v1/snapshots, GET /v1/clusters,
GET /v1/pools, and GET /v1/imports, joined into one document — useful for
a dashboard or a single scripted health check instead of five separate
calls. pools is [] (empty array) if the org has none.
| Status | When |
|---|---|
| 403 | Caller is not an admin. |
GET /v1/org/audit — audit trail
Auth: admin.
Query parameters
| Param | Type | Notes |
|---|---|---|
limit |
integer | Page size. Clamped server-side to (0, 500]; an out-of-range or omitted value falls back to 100. Must parse as an integer if present (?limit=abc is a 400, not a silent fallback). |
before |
RFC3339 timestamp | Pagination cursor — restricts the page to events strictly older than this timestamp. Compares at full precision, so pass back the exact ts of the last event on a page (RFC3339Nano) to page further without skipping same-second events. |
verify |
1 |
When set to exactly "1", adds a chain-verification pass to the response (see below). Any other value is ignored (verification is skipped, not errored). |
$ curl -s "https://api.stagdb.com/v1/org/audit?limit=3" -H "Authorization: Bearer $TOKEN"
Response 200 OK
{
"events": [
{
"seq": 102,
"actor": "[email protected]",
"action": "import.start",
"resource": "5b9d7c31-2e4f-4a6b-8c0d-1e2f3a4b5c6d",
"ts": "2026-07-18T22:10:04.812345Z",
"payload": {}
},
{
"seq": 101,
"actor": "[email protected]",
"action": "instance.launch",
"resource": "7a1e9c3d-5b2f-4c8a-9d0e-2f3a4b5c6d7e",
"ts": "2026-07-18T21:02:11.204819Z",
"payload": {}
},
{
"seq": 100,
"actor": "[email protected]",
"action": "invite.create",
"resource": "1f2e3d4c-5b6a-4978-8c9d-0e1f2a3b4c5d",
"ts": "2026-07-18T20:58:40.573062Z",
"payload": {}
}
]
}
Every state-changing action in the org is recorded: logins, invites,
instance launches/destroys, snapshot registration/share/delete, quota
changes, cluster registration, and more — as a sequenced (seq, strictly
increasing), hash-chained event. action is a dotted verb
(instance.launch, snapshot.share, invite.create, cluster.register,
…); resource is the affected object's UUID as a string. ts is
RFC3339Nano, not plain RFC3339 like every other timestamp in this API —
full sub-second precision is load-bearing for the before cursor (see
above). payload is {} when the event carries no extra structured detail.
With ?verify=1 — tamper-evident chain check
$ curl -s "https://api.stagdb.com/v1/org/audit?verify=1" -H "Authorization: Bearer $TOKEN"
{
"events": [ /* ... */ ],
"chain_ok": true,
"events_checked": 102
}
Each event is hash-chained to the one before it. verify=1 re-derives the
chain from the stored events and reports whether it's intact —
chain_ok: true/false plus events_checked. If verification fails, a
verify_error field is added with the specific reason:
{"events": [ /* ... */ ], "chain_ok": false, "events_checked": 102, "verify_error": "hash mismatch at seq 57"}
Note that chain_ok: false does not change the HTTP status — this
response is still 200 OK even when the chain is broken, since the read
succeeded; the caller (the CLI) is what turns chain_ok: false into a
non-zero exit.
Exporting
There's no separate export endpoint — page through with limit/before and
concatenate. This is exactly what adj org audit --limit 500 -o json > audit-export.json does under the hood.
| Status | When |
|---|---|
| 400 | limit present but not a valid integer ("limit must be an integer"); or before present but not a valid RFC3339 timestamp ("before must be an RFC3339 timestamp"). |
| 403 | Caller is not an admin. |