{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/sealgate-ai/json-schema/sealgate-ai-user-profile-response-schema.json",
  "title": "UserProfileResponse",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/sealgate-ai-dashboard-openapi.json#/components/schemas/UserProfileResponse",
  "properties": {
    "user_id": {
      "type": "string",
      "title": "User Id",
      "description": "User identifier (UUID)"
    },
    "email": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Email",
      "description": "User email address"
    },
    "role": {
      "type": "string",
      "title": "Role",
      "description": "User role: user, admin, or owner"
    },
    "domain": {
      "type": "string",
      "title": "Domain",
      "description": "Email domain extracted from user email"
    },
    "org_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Org Id",
      "description": "Caller's organisation identifier (UUID in the modern path, email domain for pre-backfill legacy API keys). Sourced from request.state.domain. Clients cache this locally so they can scope offline operations (e.g. seen-store quarantine decisions) without a live backend roundtrip."
    },
    "org_type": {
      "type": "string",
      "title": "Org Type",
      "description": "Always 'self_serve': org types were removed (kept for older desktop clients)",
      "default": "self_serve"
    },
    "account_status": {
      "type": "string",
      "title": "Account Status",
      "description": "Account lifecycle state: 'pending' or 'active'. Never 'disabled' - a revoked key is rejected before this endpoint runs (401).",
      "default": "active"
    },
    "edition": {
      "type": "string",
      "title": "Edition",
      "description": "Deployment edition: 'full' or a restricted one such as 'beeper'.",
      "default": "full"
    },
    "org_role": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Org Role",
      "description": "The caller's org role in this org: owner, admin or member. None when the caller has no membership here (a Super-Owner viewing another org)."
    },
    "is_super_owner": {
      "type": "boolean",
      "title": "Is Super Owner",
      "description": "True when the caller holds the super_owner instance role.",
      "default": false
    },
    "org_suspended": {
      "type": "boolean",
      "title": "Org Suspended",
      "description": "True while a Super-Owner has suspended this org (no tool calls).",
      "default": false
    },
    "multi_membership": {
      "type": "boolean",
      "title": "Multi Membership",
      "description": "True when accounts may belong to several orgs on this deployment (EDISON_MULTI_ORG plus the edition's multi_membership capability).",
      "default": false
    },
    "capabilities": {
      "$ref": "#/$defs/EditionCapabilitiesResponse",
      "description": "What this deployment exposes. The dashboard gates nav and routes on these rather than on the edition name, mirroring the backend rule, so a new edition needs no frontend change. Role is not a substitute: under EDISON_MULTI_ORG every user is an admin of their own org, so the existing admin guards filter nothing."
    }
  },
  "type": "object",
  "required": [
    "user_id",
    "role",
    "domain"
  ],
  "$defs": {
    "EditionCapabilitiesResponse": {
      "properties": {
        "server_catalog": {
          "type": "boolean",
          "title": "Server Catalog",
          "description": "Marketplace, add-server, MCP requests, server admin pages.",
          "default": true
        },
        "org_admin": {
          "type": "boolean",
          "title": "Org Admin",
          "description": "Users, roles, access control, policies, guardrails, domains.",
          "default": true
        },
        "observability": {
          "type": "boolean",
          "title": "Observability",
          "description": "Overview, audit logs, log stream, SIEM.",
          "default": true
        },
        "tool_permissions": {
          "type": "boolean",
          "title": "Tool Permissions",
          "description": "Access-control matrix and per-tool ACLs for the caller's own servers.",
          "default": true
        },
        "onboarding": {
          "type": "boolean",
          "title": "Onboarding",
          "description": "In-dashboard connect flow: onboarding tour and Connect Agent.",
          "default": true
        },
        "user_invites": {
          "type": "boolean",
          "title": "User Invites",
          "description": "Inviting other people into the caller's organisation.",
          "default": true
        },
        "stdio_tunnel_optional": {
          "type": "boolean",
          "title": "Stdio Tunnel Optional",
          "description": "Whether the local stdio tunnel is an admin-switchable rollout gate.",
          "default": true
        },
        "org_management": {
          "type": "boolean",
          "title": "Org Management",
          "description": "Creating, renaming, transferring and deleting organisations.",
          "default": true
        },
        "credit_pool": {
          "type": "boolean",
          "title": "Credit Pool",
          "description": "The account's personal credit pool that funds the orgs it owns.",
          "default": true
        },
        "org_api": {
          "type": "boolean",
          "title": "Org Api",
          "description": "The public Org API is served (the edition has it, in multi-org mode), so the developer portal works.",
          "default": true
        }
      },
      "type": "object",
      "title": "EditionCapabilitiesResponse",
      "description": "The subset of `src.edition.EditionCapabilities` the dashboard needs.\n\nOnly the flags that gate a visible surface are exposed; mount and wire-level\ncapabilities stay server-side because no client decision depends on them."
    }
  }
}