Skip to content

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.

SurfaceBase pathEnabled 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

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:

SurfacePathShapeUse it for
Admin REST/admin-apiRequest/responseNode management: install apps, create contexts and groups, manage members and aliases, inspect state.
JSON-RPC/jsonrpcRequest/responseOne-shot app calls. execute (run a method) and sync_status.
WebSocket/wsBidirectional, long-livedApp calls plus live updates over one connection: execute, subscribe, unsubscribe.
SSE/sseServer→client streamA 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 execute over JSON-RPC and the execute over 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 execute call 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 same execute request shape covers both.

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 bundled mero-auth service enforces auth in-process.

The public routes below carry no auth guard and are always reachable when the admin API is enabled.

MethodPathPurpose
GET/admin-api/healthLiveness/health check.
GET/admin-api/is-authedReports whether the caller is authenticated.
GET/admin-api/certificateReturns the node’s TLS/admin certificate.

The server applies one CORS layer to every mounted route. It allows Any origin, 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.

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 headerUse
x-auth-errorSignals the auth-failure reason. A 401 from an expired-but-refreshable token carries X-Auth-Error: token_expired.
x-auth-userThe authenticated user/key.
x-auth-permissionsThe 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.

A single endpoint accepts JSON-RPC 2.0 requests. The method field selects the operation; params carries its arguments.

MethodPathPurpose
POST/jsonrpcJSON-RPC 2.0 request dispatch.

Supported method values:

methodPurpose
executeExecute an application method against a context (mutating or query). Params: contextId, method, argsJson, optional substitute aliases.
sync_statusReport sync status.
{
"jsonrpc": "2.0",
"id": 1,
"method": "execute",
"params": {
"contextId": "<context-id>",
"method": "set",
"argsJson": { "key": "a", "value": "b" },
"substitute": []
}
}
MethodPathPurpose
GET/wsWebSocket 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:

  1. An Authorization: Bearer <jwt> header. If present, it is validated exclusively — even an invalid token here is rejected rather than retried.
  2. Only if no Authorization header is present, a ?token=<jwt> query parameter. This fallback exists because the browser WebSocket and EventSource APIs cannot set custom headers.

If the Authorization header is present, the ?token= query parameter is ignored entirely.

MethodPathPurpose
GET/sseOpen an SSE event stream.
GET/sse/session/:session_idFetch/attach to an existing SSE session.
POST/sse/subscriptionManage subscriptions for an SSE session.

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 headerMeaning
X-SSE-Session-IDThe session ID assigned to (or resumed by) this stream.
X-SSE-Reconnecttrue if this connection resumed an existing session, false for a fresh one.

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.

MethodPathPurpose
POST/admin-api/install-applicationInstall an application from a package/URL.
POST/admin-api/install-dev-applicationInstall a local dev application.
GET/admin-api/applicationsList installed applications.
GET/admin-api/applications/:application_idGet one application.
DELETE/admin-api/applications/:application_idUninstall an application.
GET/admin-api/applications/:application_id/versionsList versions of an installed application.
MethodPathPurpose
GET/admin-api/packagesList known packages.
GET/admin-api/packages/:package/versionsList versions of a package.
GET/admin-api/packages/:package/latestGet the latest version of a package.
MethodPathPurpose
GET/admin-api/contextsList context IDs.
POST/admin-api/contextsCreate a context.
POST/admin-api/contexts/invite-specialized-nodeInvite a specialized (e.g. read-only) node into a context.
GET/admin-api/contexts/:context_idGet a context.
DELETE/admin-api/contexts/:context_idDelete a context.
POST/admin-api/contexts/:context_id/applicationUpdate the context’s application.
POST/admin-api/contexts/:context_id/resyncForce a resync of the context.
GET/admin-api/contexts/for-application/:application_idList contexts for an application.
GET/admin-api/contexts/with-executors/for-application/:application_idList contexts with their executors for an application.
GET/admin-api/contexts/:context_id/storageGet context storage info.
GET/admin-api/contexts/:context_id/identitiesList identities in the context.
GET/admin-api/contexts/:context_id/identities-ownedList identities the node owns in the context.
GET/admin-api/contexts/:context_id/groupGet the context’s group.
POST/admin-api/contexts/:context_id/joinJoin a context.
POST/admin-api/contexts/:context_id/leaveLeave a context.
POST/admin-api/contexts/syncTrigger sync across all contexts.
POST/admin-api/contexts/sync/:context_idTrigger sync for one context.
MethodPathPurpose
POST/admin-api/groupsCreate a group.
GET/admin-api/groups/:group_idGet group info.
PATCH/admin-api/groups/:group_idUpdate group settings.
DELETE/admin-api/groups/:group_idDelete a group.
GET/admin-api/groups/:group_id/contextsList contexts in a group.
POST/admin-api/groups/:group_id/reparentRe-parent a group.
GET/admin-api/groups/:group_id/subgroupsList subgroups.
GET/admin-api/groups/:group_id/membersList group members.
POST/admin-api/groups/:group_id/membersAdd group members.
POST/admin-api/groups/:group_id/members/removeRemove group members.
POST/admin-api/groups/:group_id/leaveLeave a group.
PUT/admin-api/groups/:group_id/members/:identity/roleUpdate a member’s role.
GET/admin-api/groups/:group_id/metadataGet group metadata.
PUT/admin-api/groups/:group_id/metadataSet group metadata.
GET/admin-api/groups/:group_id/members/:identity/metadataGet member metadata.
PUT/admin-api/groups/:group_id/members/:identity/metadataSet member metadata.
GET/admin-api/groups/:group_id/contexts/:context_id/metadataGet context-in-group metadata.
PUT/admin-api/groups/:group_id/contexts/:context_id/metadataSet context-in-group metadata.
POST/admin-api/groups/:group_id/contexts/:context_id/removeDetach a context from a group.
POST/admin-api/groups/:group_id/upgradeUpgrade a group.
GET/admin-api/groups/:group_id/upgrade/statusGet group upgrade status.
POST/admin-api/groups/:group_id/upgrade/retryRetry a group upgrade.
GET/admin-api/groups/:namespace_id/cascade-statusGet cascade status (by namespace).
GET/admin-api/groups/:namespace_id/migration-statusGet migration status (by namespace).
POST/admin-api/groups/:namespace_id/migration/abortAbort a migration (by namespace).
POST/admin-api/groups/:group_id/signing-keyRegister a signing key.
POST/admin-api/groups/:group_id/issue-ownership-proofIssue a group ownership proof.
POST/admin-api/groups/:group_id/issue-namespace-ownership-proofIssue a namespace ownership proof.
POST/admin-api/groups/:group_id/syncSync a group.
POST/admin-api/groups/:group_id/join-via-inheritanceJoin a subgroup via inheritance.
GET/admin-api/groups/:group_id/members/:identity/capabilitiesGet a member’s capabilities.
PUT/admin-api/groups/:group_id/members/:identity/capabilitiesSet a member’s capabilities.
PUT/admin-api/groups/:group_id/members/:identity/auto-followSet a member’s auto-follow flag.
PUT/admin-api/groups/:group_id/settings/default-capabilitiesSet group default capabilities.
GET/admin-api/groups/:group_id/settings/tee-admission-policyGet the group’s TEE admission policy.
PUT/admin-api/groups/:group_id/settings/tee-admission-policySet the group’s TEE admission policy.
PUT/admin-api/groups/:group_id/settings/subgroup-visibilitySet subgroup visibility.
POST/admin-api/groups/:group_id/inviteCreate a group invitation (legacy).
POST/admin-api/groups/joinJoin a group (legacy).
MethodPathPurpose
GET/admin-api/namespacesList namespaces.
POST/admin-api/namespacesCreate a namespace.
GET/admin-api/namespaces/:namespace_idGet a namespace.
DELETE/admin-api/namespaces/:namespace_idDelete a namespace.
POST/admin-api/namespaces/:namespace_id/inviteInvite into a namespace.
POST/admin-api/namespaces/:namespace_id/joinJoin a namespace.
POST/admin-api/namespaces/:namespace_id/leaveLeave a namespace.
GET/admin-api/namespaces/:namespace_id/identityGet the node’s identity in a namespace.
GET/admin-api/namespaces/for-application/:application_idList namespaces for an application.
GET/admin-api/namespaces/:namespace_id/groupsList groups in a namespace.
POST/admin-api/namespaces/:namespace_id/groupsCreate a group inside a namespace.
MethodPathPurpose
PUT/admin-api/blobsUpload a blob.
GET/admin-api/blobsList blobs.
GET/admin-api/blobs/:blob_idDownload a blob.
HEAD/admin-api/blobs/:blob_idGet blob info/metadata (headers only).
DELETE/admin-api/blobs/:blob_idDelete a blob.
MethodPathPurposeAuth
GET/admin-api/tee/infoTEE info.Public
POST/admin-api/tee/attestProduce/verify an attestation.Public
POST/admin-api/tee/verify-quoteVerify a TEE quote.Public
POST/admin-api/tee/fleet-joinJoin a TEE fleet.Protected
MethodPathPurpose
POST/admin-api/identity/contextGenerate a new context identity (keypair).
POST/admin-api/alias/create/contextCreate an alias for a context.
POST/admin-api/alias/create/applicationCreate an alias for an application.
POST/admin-api/alias/create/identity/:contextCreate an alias for an identity within a context.
POST/admin-api/alias/lookup/context/:nameResolve a context alias.
POST/admin-api/alias/lookup/application/:nameResolve an application alias.
POST/admin-api/alias/lookup/identity/:context/:nameResolve an identity alias within a context.
POST/admin-api/alias/delete/context/:nameDelete a context alias.
POST/admin-api/alias/delete/application/:nameDelete an application alias.
POST/admin-api/alias/delete/identity/:context/:nameDelete an identity alias within a context.
GET/admin-api/alias/list/contextList context aliases.
GET/admin-api/alias/list/applicationList application aliases.
GET/admin-api/alias/list/identity/:contextList identity aliases within a context.
MethodPathPurpose
GET/admin-api/network/statuslibp2p connectivity snapshot (relays, rendezvous, DCUtR, AutoNAT).
GET/admin-api/peersConnected peers count.
GET/admin-api/usagePer-namespace usage (counts and on-disk bytes).