Skip to Content
MuoCeon Docs
v1oauth context

Authorized applications

GET /v1/oauth/grants and DELETE /v1/oauth/grants/:clientId — the only entry point to authorization relationships.

Authorization relationships are created by oauth when it issues tokens, and only oauth knows how many sessions an application currently holds. The auth context only knows "which devices the user signed in on"; its session records contain no client authorization data, so this data is not duplicated on the auth side.

Endpoints

MethodPathPurposeRequirements
GET/v1/oauth/grantsList authorized applicationsaud=oauth, scope oauth:grants:read
DELETE/v1/oauth/grants/:clientIdRevoke an application's authorizationaud=oauth, scope oauth:grants:revoke, max_age=300

The caller is the management console: it uses RFC 8693 token exchange to turn an auth session token into a short-lived oauth-audience resource token (5 minutes, never persisted, audience trimmed to oauth / account).

GET /grants

Query

ParameterTypeRequiredNotes
limitnumberOptionalDefault 20, max 100
cursorstringOptionalCursor from the previous page
kindfirst_party | third_partyOptionalFetch only one section

Response

{
  "success": true,
  "grants": [
    {
      "client_id": "cli_...",
      "name": "Example App",
      "client_type": "third_party",
      "did": null,
      "scopes": ["openid", "profile"],
      "session_count": 2,
      "authorized_at": "2026-10-02T12:00:00.000Z",
      "last_issued_at": "2026-11-13T09:21:00.000Z"
    }
  ],
  "next_cursor": null
}
FieldNotes
didDevice id for a first-party authorization; null for third parties
user_agentRaw UA of that device's most recent sign-in; absent for third parties
session_countSessions this application currently holds
scopesCurrently effective scope set

Ordered by most recent issuance. First-party clients are aggregated per device, so the same application may appear on several rows — each with a different did, revocable individually.

Why fetch by kind

Each section paginates independently. If they were merged into one "most recently active" page and split client-side, a section would look empty while its entries actually sat on later pages.

DELETE /grants/:clientId

Parameters

ParameterLocationRequiredNotes
clientIdpath✅Application to revoke
didqueryOptionalRevoke only that device; the whole application when omitted
{ "success": true, "message": "Authorization revoked", "revoked": 2 }
SemanticsNotes
Without didThird-party semantics: kill the application's access on every device
With didFirst-party semantics: kill the authorization on that one device

did is a query parameter, not a path segment

It narrows the same relationship; it is not another resource. An extra path segment would make "application" and "device" look like two levels of entity.

Revocation is a one-shot destructive action, so it requires max_age=300; the read-only list does not. It does not accept RFC 9396 authorization details — that belongs to /authorize.

On this page