Admin & JSON-RPC API Reference
The node’s HTTP server (default bind /ip4/127.0.0.1/tcp/2528 and
/ip6/::1/tcp/2528) exposes four
surfaces: a REST-style admin API, a JSON-RPC endpoint for app
execution, a WebSocket stream, and a Server-Sent Events stream. Every
path below is taken directly from the axum routers in the server crate.
Base paths
Section titled “Base paths”| Surface | Base path | Enabled by |
|---|---|---|
| Admin API | /admin-api |
[server.admin] enabled = true |
| JSON-RPC | /jsonrpc |
[server.jsonrpc] enabled = true |
| WebSocket | /ws |
[server.websocket] enabled = true |
| Server-Sent Events | /sse |
[server.sse] enabled = true |
| Admin dashboard UI | /admin-dashboard |
[server.admin] enabled = true |
Every request body on these surfaces is a closed set. A body carrying a field the node does not declare is a 400 at deserialization, never a silent drop, so a client built against a different shape fails loudly instead of installing, joining, or upgrading something it did not name. Query strings stay lenient.
Choosing an API surface
Section titled “Choosing an API surface”All four surfaces are mounted on a single HTTP server and wrapped by the same optional auth layer — when embedded auth is on, every one of them is guarded identically; when it is off, all four are open. They differ in shape, not in how they authenticate:
| Surface | Path | Shape | Use it for |
|---|---|---|---|
| Admin REST | /admin-api |
Request/response | Node management: install apps, create contexts and groups, manage members and aliases, inspect state. |
| JSON-RPC | /jsonrpc |
Request/response | One-shot app calls. execute (run a method) and sync_status. |
| WebSocket | /ws |
Bidirectional, long-lived | App calls plus live updates over one connection: execute, subscribe, unsubscribe. |
| SSE | /sse |
Server→client stream | A read-only event feed when you only need to receive events (no custom request headers needed). |
Two practical notes:
- There is one execute, reached two ways. The
executeover JSON-RPC and theexecuteover WebSocket resolve to the same execution kernel — same executor resolution, same runtime invocation, same result envelope. Pick JSON-RPC for a single stateless call; pick WebSocket when you also want to subscribe to events on the same connection. - Query vs. mutate is not a flag you set. Whether an
executecall only reads state or commits a change is decided by the target method’s own#[app::view]declaration in the app, not by the transport or any request field. The sameexecuterequest shape covers both.
Authentication
Section titled “Authentication”Admin routes split into protected and public sets. The protected set is
wrapped in an auth guard whose behavior depends on [server] auth_mode:
proxy(default) — the node expects an external auth proxy in front of it.embedded— the bundledmero-authservice enforces auth in-process.
The public routes below carry no auth guard and are always reachable when the admin API is enabled.
| Method | Path | Purpose |
|---|---|---|
| GET | /admin-api/health |
Liveness/health check. |
| GET | /admin-api/is-authed |
Reports whether the caller is authenticated. |
CORS and browser / Tauri clients
Section titled “CORS and browser / Tauri clients”The server applies one CORS layer to every mounted route. With embedded auth it
allows Any origin (or the [server.cors] allowed_origins list when set),
Any request header, the methods GET/POST/PUT/PATCH/DELETE/OPTIONS,
and sets allow_private_network(true) so requests from a public-origin page to
a loopback node pass the browser’s private-network preflight.
In proxy auth mode the node checks no caller itself, so it judges every browser
request: one that carries an Origin, or the Sec-Fetch-Site header a browser
sends even on a same-origin GET. (Sec-Fetch-Mode alone does not count: Node’s
built-in fetch sends it on every request.) Such a request is served when:
- its origin is listed in
[server.cors] allowed_origins; or - its origin is a loopback page (
localhost,*.localhost,127.0.0.0/8,[::1], any port), including the desktop webview’stauri://localhost, whatever host it calls; or - every host it names (
Host, andX-Forwarded-Hostif present) is one of the node’s own, and the origin is the node’s own origin (it matches one of those hosts) or absent.
The loopback rule means that in proxy mode any page served from localhost can reach the admin API, whatever port it is on. Use proxy mode only on a development machine or behind a proxy that checks every caller.
A host is the node’s own when it is a loopback name, an IP address, or the host
of an allowed_origins entry. A browser’s Host is whatever name it resolved,
so on its own it proves nothing: under DNS rebinding a page on
attacker.example re-points its name at the node and sends that name as both
Origin and Host. A node served to browsers under a host name of its own,
for example behind a proxy at https://node.example.com, must list that origin
in allowed_origins, or its own pages are refused.
Any other browser request gets 403 before a handler runs, on every route
including /jsonrpc, /ws and /sse, and CORS does not answer it.
A WebSocket upgrade is held to this rule with embedded auth as well; see WebSocket.
Private-network access is advertised only to origins listed in
allowed_origins. Requests with neither an Origin nor Sec-Fetch-Site (curl,
meroctl, SDKs outside a browser, Node’s fetch) are unaffected, whatever host
they name.
Because the response uses Any origin, allow_credentials is intentionally
not set (the two are incompatible per the CORS spec, so enabling it would be a
no-op for browsers). Cookie/credentialed auth therefore does not work against
the default configuration; pass tokens via the Authorization header instead.
Cross-origin clients (browser SPAs, Tauri webviews) can only read response headers that the server explicitly exposes. The layer exposes exactly three:
| Exposed header | Use |
|---|---|
x-auth-error |
Signals the auth-failure reason. A 401 from an expired-but-refreshable token carries X-Auth-Error: token_expired. |
x-auth-user |
The authenticated user: an opaque ID, stable across logins and token refreshes; a password reset issues a new one. |
x-auth-permissions |
The caller’s resolved permissions. |
To implement transparent refresh-on-401, read X-Auth-Error on a 401: if it is
token_expired, refresh the access token and retry; otherwise treat it as a
hard auth failure. If these headers are not exposed (e.g. behind a proxy that
strips them), every access-token expiry surfaces as a hard logout instead.
JSON-RPC
Section titled “JSON-RPC”A single endpoint accepts JSON-RPC 2.0 requests. The method field selects the
operation; params carries its arguments.
| Method | Path | Purpose |
|---|---|---|
| POST | /jsonrpc |
JSON-RPC 2.0 request dispatch. |
Supported method values:
method |
Purpose |
|---|---|
execute |
Execute an application method against a context (mutating or query). Params: contextId, method, argsJson, optional substitute aliases. |
sync_status |
Report sync status. |
{ "jsonrpc": "2.0", "id": 1, "method": "execute", "params": { "contextId": "<context-id>", "method": "set", "argsJson": { "key": "a", "value": "b" }, "substitute": [] }}WebSocket
Section titled “WebSocket”| Method | Path | Purpose |
|---|---|---|
| GET | /ws |
WebSocket upgrade. Carries execute, subscribe, and unsubscribe messages over the socket. |
When embedded auth is enabled, the auth guard runs at the HTTP upgrade request, before the socket is established — an unauthenticated upgrade is rejected with a 401 and never becomes a WebSocket. The guard resolves the token in this order:
- An
Authorization: Bearer <jwt>header. If present, it is validated exclusively — even an invalid token here is rejected rather than retried. - Only if no
Authorizationheader is present, a?token=<jwt>query parameter. This fallback exists because the browserWebSocketandEventSourceAPIs cannot set custom headers.
If the Authorization header is present, the ?token= query parameter is
ignored entirely.
A WebSocket has no CORS, so the node judges a browser’s upgrade by its origin itself, in every auth mode, by the same rule that proxy auth mode applies to every route (see CORS and browser / Tauri clients).
With embedded auth the token is checked first: an upgrade without a valid token gets 401 whatever its origin, and a page the origin rule does not admit gets 403 only when it carries a valid token.
So an app hosted on another origin must be listed in [server.cors] allowed_origins to open a socket, as well as hold a token.
A GET /ws that is not a WebSocket upgrade gets 400.
A client that sends neither Origin nor Sec-Fetch-Site is not a browser and is unaffected.
The upgrade needs context:subscribe. Each execute message is then checked
against the same token for context:execute on its context (and method, for a
method-scoped grant), so a subscribe-only token can subscribe but its execute
messages are refused. /jsonrpc calls are held to the same check. In proxy auth
mode the node takes the token’s permissions from the X-Auth-Permissions header
the proxy forwards; see Where a scope is checked.
Server-Sent Events
Section titled “Server-Sent Events”| Method | Path | Purpose |
|---|---|---|
| GET | /sse |
Open an SSE event stream. |
| GET | /sse/session/:session_id |
Fetch/attach to an existing SSE session. |
| POST | /sse/subscription |
Manage subscriptions for an SSE session. |
Open the stream with EventSource or fetch.
A browser request that no script opened, such as navigating to /sse or loading it as an image or a frame (Sec-Fetch-Mode other than cors or same-origin), gets 403 and creates no session.
Clients that are not browsers (curl, SDKs on a server) send no Sec-Fetch-Mode and are unaffected.
SSE durability and reconnection
Section titled “SSE durability and reconnection”The SSE stream uses a skip-on-disconnect delivery model: there is no replay buffer. Sessions persist (subscriptions and a monotonic event counter survive a reconnect), but any event emitted while a client is disconnected is lost and never redelivered. Event IDs are sequential, so a gap in the IDs a client receives is the signal that events were missed.
On connect the response carries two headers for the client to track its session:
| Response header | Meaning |
|---|---|
X-SSE-Session-ID |
The session ID assigned to (or resumed by) this stream. |
X-SSE-Reconnect |
true if this connection resumed an existing session, false for a fresh one. |
Subscribing is a separate POST /sse/subscription naming the session ID from
the connect frame. Its response is the readiness signal: once it answers
200 and lists a context in contexts, every later event for that context
reaches the stream. A client that needs to observe something it is about to
trigger must wait for that response, not merely for the stream to open. A
context the caller may not observe is dropped from contexts rather than
refused, so check the list.
To reconnect, the client sends the Last-Event-ID header. Event IDs have the
format {session_id}-{n}; the server parses the session_id prefix to restore
the session. Sessions expire after 24 hours of inactivity, after which a
reconnect attempt starts a fresh session. The stream also advertises a retry
hint of 3000ms in its initial event.
Admin API — Applications
Section titled “Admin API — Applications”| Method | Path | Purpose |
|---|---|---|
| POST | /admin-api/install-application |
Install package@version from the node’s configured registry. |
| POST | /admin-api/install-dev-application |
Install a local dev application. |
| GET | /admin-api/applications |
List installed applications. |
| GET | /admin-api/applications/:application_id |
Get one application. |
| GET | /admin-api/applications/:application_id/abi |
Get the application’s embedded WASM ABI manifest (optional ?service_name=). |
| DELETE | /admin-api/applications/:application_id |
Uninstall an application. |
| GET | /admin-api/applications/:application_id/versions |
List versions of an installed application. |
Packages
Section titled “Packages”| Method | Path | Purpose |
|---|---|---|
| GET | /admin-api/packages |
List known packages. |
| GET | /admin-api/packages/:package/versions |
List versions of a package. |
| GET | /admin-api/packages/:package/latest |
Get the latest version of a package. |
Admin API — Contexts
Section titled “Admin API — Contexts”| Method | Path | Purpose |
|---|---|---|
| GET | /admin-api/contexts |
List context IDs. |
| POST | /admin-api/contexts |
Create a context. |
| GET | /admin-api/contexts/:context_id |
Get a context. |
| DELETE | /admin-api/contexts/:context_id |
Delete a context. |
| POST | /admin-api/contexts/:context_id/application |
Update the context’s application. |
| POST | /admin-api/contexts/:context_id/resync |
Force a resync of the context. |
| GET | /admin-api/contexts/:context_id/intents |
Relay descriptor: the account and signing key a warrant must name (executorAccount, executorKey), the release it must pin (releaseBytecodeId, releaseVersion), and whether this node relays delegated writes for the context (canAuthorOnBehalf). See delegated authorship. |
| POST | /admin-api/contexts/:context_id/intents |
Execute a member’s signed intent under their warrant; 403 if this node may not relay. See delegated authorship. |
| GET | /admin-api/contexts/for-application/:application_id |
List contexts for an application. |
| GET | /admin-api/contexts/with-executors/for-application/:application_id |
List contexts with their executors for an application. |
| GET | /admin-api/contexts/:context_id/storage |
Get context storage info. |
| GET | /admin-api/contexts/:context_id/identities |
List identities in the context. |
| GET | /admin-api/contexts/:context_id/identities-owned |
List identities the node owns in the context. |
| GET | /admin-api/contexts/:context_id/group |
Get the context’s group. |
| POST | /admin-api/contexts/:context_id/join |
Join a context. |
| POST | /admin-api/contexts/:context_id/leave |
Leave a context. |
| POST | /admin-api/contexts/sync |
Trigger sync across all contexts. |
| POST | /admin-api/contexts/sync/:context_id |
Trigger sync for one context. |
Admin API — Groups
Section titled “Admin API — Groups”| Method | Path | Purpose |
|---|---|---|
| POST | /admin-api/groups |
Create a group. A nested group is created Open unless the body sets visibility: "restricted". |
| GET | /admin-api/groups/:group_id |
Get group info. |
| PATCH | /admin-api/groups/:group_id |
Update group settings. |
| DELETE | /admin-api/groups/:group_id |
Delete a group. |
| GET | /admin-api/groups/:group_id/contexts |
List contexts in a group. |
| POST | /admin-api/groups/:group_id/reparent |
Re-parent a group. |
| GET | /admin-api/groups/:group_id/subgroups |
List subgroups. |
| GET | /admin-api/groups/:group_id/members |
List group members. |
| POST | /admin-api/groups/:group_id/members |
Add group members, each named by account, or by key written key:<64-hex>. Every id is hex, so the tag is what tells the two apart — an untagged key is read as an account. |
| POST | /admin-api/groups/:group_id/members/remove |
Remove group members. |
| POST | /admin-api/groups/:group_id/accounts/:account/seal |
Seal a payload to that account’s root key, as this group sees it. Body { plaintext }, hex, at most 64 KiB and never empty; returns { accountRootEpoch, ephemeralPublicKey, nonce, ciphertext }. Caller and target must both be group members, and a non-member is refused identically to an unknown account. Confidentiality only — the sender key is ephemeral and unauthenticated, so anyone knowing a root public key can produce an envelope for it. |
| POST | /admin-api/groups/:group_id/leave |
Leave a group. |
| PUT | /admin-api/groups/:group_id/members/:identity/role |
Update a member’s role. |
| GET | /admin-api/groups/:group_id/metadata |
Get group metadata. |
| PUT | /admin-api/groups/:group_id/metadata |
Set group metadata. |
| GET | /admin-api/groups/:group_id/members/:identity/metadata |
Get member metadata. |
| PUT | /admin-api/groups/:group_id/members/:identity/metadata |
Set member metadata. |
| GET | /admin-api/groups/:group_id/contexts/:context_id/metadata |
Get context-in-group metadata. |
| PUT | /admin-api/groups/:group_id/contexts/:context_id/metadata |
Set context-in-group metadata. |
| POST | /admin-api/groups/:group_id/contexts/:context_id/remove |
Detach a context from a group. |
| POST | /admin-api/groups/:group_id/upgrade |
Upgrade a group. |
| GET | /admin-api/groups/:group_id/upgrade/status |
Get group upgrade status. |
| POST | /admin-api/groups/:group_id/upgrade/retry |
Retry a group upgrade. |
| POST | /admin-api/groups/:namespace_id/upgrade/activate |
Switch this node’s contexts of a namespace to its stored target release and replay the deltas held for them. Never fetches or installs a release: 404 naming the first release a context would step through (each upgrade rung, then the target) that is not installed. Takes the namespace root (400 for a subgroup). Optional body fields expectedApplicationId and expectedVersion; 409 naming the group when the namespace or any subgroup being switched targets another application, or when the namespace’s target release is another version. Answers 200 with targetApplicationId, switchedContexts, replayedDeltas and failedContexts ({contextId, error, retryable} per context that did not finish, empty when all did); calling again retries only those. |
| GET | /admin-api/groups/:namespace_id/cascade-status |
Get cascade status (by namespace). |
| GET | /admin-api/groups/:namespace_id/migration-status |
Get migration status (by namespace). |
| POST | /admin-api/groups/:namespace_id/migration/abort |
Abort a migration (by namespace). |
| POST | /admin-api/groups/:group_id/issue-ownership-proof |
Issue a group ownership proof. |
| POST | /admin-api/groups/:group_id/issue-namespace-ownership-proof |
Issue a namespace ownership proof. Beside the signed proof the answer carries founding ({ founderAccountId, salt }) and credential (hex borsh AccountProof<DeviceCert> over the signing key), unsigned and self-verifying, so a verifier without governance state can confirm the signer is a node of the account that founded the namespace. Each is absent when the node cannot produce it. |
| POST | /admin-api/groups/:group_id/sync |
Sync a group. |
| POST | /admin-api/groups/:group_id/join-via-inheritance |
Join a subgroup via inheritance. |
| GET | /admin-api/groups/:group_id/members/:identity/capabilities |
Get a member’s capabilities. |
| PUT | /admin-api/groups/:group_id/members/:identity/capabilities |
Set a member’s capabilities. |
| PUT | /admin-api/groups/:group_id/members/:identity/auto-follow |
Set a member’s auto-follow flag. |
| PUT | /admin-api/groups/:group_id/settings/default-capabilities |
Set group default capabilities. |
| GET | /admin-api/groups/:group_id/settings/tee-admission-policy |
Get the group’s TEE admission policy, including its mode. |
| PUT | /admin-api/groups/:group_id/settings/tee-admission-policy |
Set the group’s TEE admission policy: measurement lists, or signedRelease to admit any signed mero-tee release of the named profiles. Optional mode, "replica" (default) or "relay", picks the role admitted TEEs get and converts those already admitted — see replica or relay. |
| PUT | /admin-api/groups/:group_id/settings/subgroup-visibility |
Set subgroup visibility. |
| POST | /admin-api/groups/:group_id/invite |
Create a group invitation (legacy). |
| POST | /admin-api/groups/join |
Join a group (legacy). |
Admin API — Namespaces
Section titled “Admin API — Namespaces”| Method | Path | Purpose |
|---|---|---|
| GET | /admin-api/namespaces |
List namespaces. |
| POST | /admin-api/namespaces |
Create a namespace. |
| GET | /admin-api/namespaces/:namespace_id |
Get a namespace. |
| DELETE | /admin-api/namespaces/:namespace_id |
Remove a namespace from this node. Any member may; nothing is published and the account stays a member. |
| POST | /admin-api/namespaces/:namespace_id/invite |
Invite into a namespace. Body may name admitters and admitterAddrs — see below. |
| POST | /admin-api/namespaces/:namespace_id/join |
Join a namespace. A refusal carries a code — see below. |
| POST | /admin-api/namespaces/:namespace_id/admit |
Publish a join signed by a keyholder that has no node of its own. Takes no credential on any node: the signed op is the authorization, and a node the invitation does not name refuses it 403. A join already applied here answers published: false. See Direct Admission. |
| POST | /admin-api/namespaces/:namespace_id/leave |
Leave a namespace. |
| GET | /admin-api/namespaces/:namespace_id/revoked-devices |
Device ids revoked in the namespace (revokedDevices) and sha256(account || device) of devices an account withdrew there (withdrawnSlots). Admin only, on a member node. |
| GET | /admin-api/namespaces/for-application/:application_id |
List namespaces for an application. |
Join refusals
Section titled “Join refusals”A refused join (/namespaces/:namespace_id/join and /groups/join) answers
{ "error": <message>, "code": <code> }. The status says whether trying again can
help; the code says which refusal it was, since several share a status and
each asks something different of the person joining.
code |
Status | Meaning |
|---|---|---|
invitation_expired |
409 | The invitation’s 24-hour window has passed. A new invitation is needed. |
invitation_invalid |
400 | The invitation is missing something a join needs. A new invitation is needed. |
invitation_already_used |
409 | This identity joined with this invitation before and has since left. A new invitation is needed. |
removed_from_group |
409 | An admin removed this identity. No invitation readmits it; an admin must re-add it. |
reentry_blocked |
409 | This identity left and cannot come back by inheritance; it must be re-invited or re-added. |
join_refused_by_member |
503 | Every member that answered refused; the message quotes the last one’s reason. Retryable: a member behind on the namespace’s history refuses what it has not seen yet. |
no_admitter_reached |
503 | A member answered but is not an admitter the invitation names. Retry once one is online. |
no_member_reachable |
504 | No member of the namespace answered. Retry once the inviting node is online. |
Any other failure has no code.
Invitation body: admitters and addresses
Section titled “Invitation body: admitters and addresses”Both /groups/:group_id/invite and /namespaces/:namespace_id/invite accept the
same body. Every field is optional.
{ "expirationTimestamp": 3600, "recursive": false, "admitters": ["8f2c…e1", "b04a…77"], "admitterAddrs": [ "/ip4/203.0.113.7/tcp/2528/p2p/12D3KooWExample" ]}| field | meaning |
|---|---|
expirationTimestamp |
Validity in seconds, clamped to 24 hours. Not an absolute time despite the name. |
recursive |
Also mint invitations for the namespace’s child groups. |
admitters |
Accounts allowed to admit a claim, 64 hex each. Signed into the invitation. Omit and the node fills in the group’s admins plus its TEE nodes; it refuses to mint if that set is empty. |
admitterAddrs |
libp2p multiaddrs for those admitters, each including its /p2p/<peer-id> suffix. Not signed. Omit and the node fills in what it knows. |
The peer id has to be in the address: a joiner cannot resolve an account to a peer without governance state, which is precisely what it has not synced yet.
Supplied addresses are used as given and are not merged with the node’s own view — a caller naming one is usually correcting that view, not extending it.
Because they are unsigned, a wrong address costs a failed dial and nothing more:
libp2p authenticates the peer id on connect, and the signed admitters list still
decides who may answer. Direct Admission covers the
split.
Admin API — Blobs
Section titled “Admin API — Blobs”| Method | Path | Purpose |
|---|---|---|
| PUT | /admin-api/blobs |
Upload a blob. Optional ?hash=<hex> to verify the content, and ?context_id=<id> to share it in a context this node is a member of (400 for any other context, and nothing is stored). Peers are served only blobs held for the context they ask under, so a blob uploaded without a context stays local. |
| GET | /admin-api/blobs |
List blobs. |
| GET | /admin-api/blobs/:blob_id |
Download a blob. Optional ?context_id=<id>: if this node does not hold the blob, look for it among the context’s peers and download it from one. |
| HEAD | /admin-api/blobs/:blob_id |
Get blob info/metadata (headers only). Optional ?context_id=<id>: see below. |
| DELETE | /admin-api/blobs/:blob_id |
Delete a blob. |
A GET or HEAD that a page on another site caused without a script, such as a link, a navigation or an <img> (Sec-Fetch-Site: cross-site with a Sec-Fetch-Mode other than cors), is answered from this node’s own store only: context_id does not make the node ask its peers, and a blob it does not hold is 404.
A fetch from an admitted origin, a page the node serves and a client that is not a browser are unaffected.
HEAD with ?context_id=
Section titled “HEAD with ?context_id=”Without the parameter, HEAD answers only about blobs this node holds — one
local store read, and a 404 for anything else.
With it, a local miss falls through to the same bounded peer search GET uses,
but stops at the header a holder sends before its first chunk: HEAD never
transfers the blob. Discovery is opt-in for a reason — a search can run to the
node’s 30s discovery deadline, while HEAD otherwise reads as a cheap call.
X-Blob-Source says where the answer came from, and which other headers you get:
X-Blob-Source |
Meaning | Headers |
|---|---|---|
local |
This node holds the blob. | Content-Length, Content-Type, ETag, X-Blob-ID, X-Blob-Hash, X-Blob-MIME-Type |
peer |
Only a context peer holds it. | Content-Length (the size that peer reported, omitted if it reported none), X-Blob-ID |
ETag, Content-Type, X-Blob-Hash and X-Blob-MIME-Type are absent from a
peer answer because every one of them is computed from the bytes — the content
hash from local metadata, the MIME type sniffed from the first chunk — and this
node does not have them. They are omitted rather than guessed. A blob held
neither locally nor by any probed peer is still a 404.
Private blobs need the same signed membership proof on this path as on GET; a
peer answers “not held” to an unauthorized probe, so discovery is no weaker and
no stronger than the download path.
Admin API — TEE
Section titled “Admin API — TEE”| Method | Path | Purpose | Auth |
|---|---|---|---|
| GET | /admin-api/tee/info |
TEE info. | Public |
| POST | /admin-api/tee/attest |
Produce an attestation, optionally binding keys and carrying its collateral. | Public |
| POST | /admin-api/tee/registration-attest |
Produce an attestation carrying the registration binding, for fleet registration. | Protected |
| POST | /admin-api/tee/fleet-join |
Join a TEE fleet. | Protected |
Admin API — Identity & Alias
Section titled “Admin API — Identity & Alias”| Method | Path | Purpose |
|---|---|---|
| GET | /admin-api/identity |
Get this node’s account and device identity. Replaced the per-namespace route: identity is node-level, one root to one account to one device. |
| DELETE | /admin-api/identity/revoked-from |
Acknowledge that this node’s device was revoked, clearing revokedFrom from GET /admin-api/identity. A no-op when nothing is recorded. |
| POST | /admin-api/identity/context |
Generate a new context identity (keypair). |
| POST | /admin-api/alias/create/context |
Create an alias for a context. |
| POST | /admin-api/alias/create/application |
Create an alias for an application. |
| POST | /admin-api/alias/create/device |
Create an alias for a device. |
| POST | /admin-api/alias/lookup/context/:name |
Resolve a context alias. |
| POST | /admin-api/alias/lookup/application/:name |
Resolve an application alias. |
| POST | /admin-api/alias/lookup/device/:name |
Resolve a device alias. |
| POST | /admin-api/alias/delete/context/:name |
Delete a context alias. |
| POST | /admin-api/alias/delete/application/:name |
Delete an application alias. |
| POST | /admin-api/alias/delete/device/:name |
Delete a device alias. |
| GET | /admin-api/alias/list/context |
List context aliases. |
| GET | /admin-api/alias/list/application |
List application aliases. |
| GET | /admin-api/alias/list/device |
List device aliases. |
Admin API — Network & Usage
Section titled “Admin API — Network & Usage”| Method | Path | Purpose |
|---|---|---|
| GET | /admin-api/network/status |
libp2p connectivity snapshot (relays, rendezvous, DCUtR, AutoNAT). |
| GET | /admin-api/peers |
Connected peers count. |
| GET | /admin-api/usage |
Per-namespace usage (counts and on-disk bytes). |